• File: index.php
  • Full Path: C:/htdocs/reeft_gps-20250621173158/index.php
  • Date Modified: 05/09/2025 11:35 AM
  • File size: 201.55 KB
  • MIME-type: text/x-php
  • Charset: utf-8
<?php
//======================================================================================
//
// Function: Main menu for GPS
//
// Programmer: AR
// Date      : 2024-10-08
//
// Copyright Reeft A/S (c) - 2024
//======================================================================================

header("Access-Control-Allow-Origin: *"); // Or specify a specific origin
header("Access-Control-Allow-Methods: POST, GET, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization");

// Handle preflight requests
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit;
}

//======================================================================================	
// Set session
//======================================================================================			
if(!isset($_SESSION))
{ 
	session_start();
}

//======================================================================================
// General 
//======================================================================================
include "include/apikey.php";
include "include/config.php";


// Check if the token is already in the session
if (!isset($_SESSION['TargetOrganization']) || !isset($_REQUEST['TargetOrganization']) || $_SESSION['TargetOrganization'] != $_REQUEST['TargetOrganization']) {
    // Include the token validation
    include_once "token_validation.php";
}

//======================================================================================
// Language data  ["en", "de", "da", "no", "sv"]
//======================================================================================
$loginLanguage = $_SESSION['loginLanguage'];
include "language/$loginLanguage.php";

?>

<!DOCTYPE html>
<html lang="en">
<head>
	<title>GPS</title>

	<meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
	<meta name="description" content="REEFT GPS">
    <meta name="author" content="REEFT A/S">
    <link rel="icon" href="images/favicon/favicon.ico">
	
	<link href="javascript/bootstrap-5.3.3/css/bootstrap.min.css" rel="stylesheet">
	<link href="javascript/chosen_v1.8.7/chosen.css" rel="stylesheet" type="text/css">	
	<link rel="stylesheet" href="javascript/jquery-ui-1.14.1/jquery-ui.css">
    
	<link href="javascript/fontawesome/6.5.1/css/all.min.css" rel="stylesheet" type="text/css">
	<link href="javascript/fontawesome/6.5.1/css/sharp-solid.min.css" rel="stylesheet" type="text/css">

	
	<link href="css/sticky-footer.css" rel="stylesheet" type="text/css">
	
	<script src="javascript/jquery-3.7.1.min.js"></script>
	<script src="javascript/jquery-ui-1.14.1/jquery-ui.min.js"></script>
	<script src="javascript/popper.min.js"></script>
	
	<script src="javascript/ajaxq/ajaxq.js"></script>
	
	<script src="javascript/bootstrap-5.3.3/js/bootstrap.min.js"></script>
	<script src="javascript/chosen_v1.8.7/chosen.jquery.min.js" type="text/javascript"></script>	
	
	<script type="text/javascript" src="javascript/markerclusterer.min.js"></script>  
    <script type="text/javascript" src="javascript/infobubble.js"></script>
	
	<script type="text/javascript" src="javascript/xlxs-0.15.6/xlsx.full.min.js"></script> 

	<link href="css/main.css" rel="stylesheet">
	
	 <!-- Loads the Google Maps API script asynchronously, the script runs only after the HTML document has been fully parsed  -->
	<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry&key=<?php echo $apikey; ?>&callback=initMap&v=<?php echo time(); ?>" async defer></script>


<script language="JavaScript">

//=============================================================================
// Globals
//=============================================================================

//variables from REEFT 2.0
var token 						= '<?php echo $_SESSION['token']; ?>';
var loginOrganizationId 		= '<?php echo $_SESSION['loginOrganizationId']; ?>';
var loginOrganizationName 		= '<?php echo $_SESSION['loginOrganizationName']; ?>';
var loginUserId 				= '<?php echo $_SESSION['loginUserId']; ?>';
var loginUserName 				= '<?php echo $_SESSION['loginUserName']; ?>';
var loginUserRole 				= '<?php echo $_SESSION['loginUserRole']; ?>';
var loginDepartmentId 			= '<?php echo $_SESSION['loginDepartmentId']; ?>';
var loginDepartmentName 		= '<?php echo $_SESSION['loginDepartmentName']; ?>';

var dftMapCenterLat 			= <?php echo $DFT_MAP_CENTER_LAT; ?>;
var dftMapCenterLng 			= <?php echo $DFT_MAP_CENTER_LNG; ?>;
var dftZoomlevel	 			= <?php echo $DFT_ZOOMLEVEL; ?>;
var gsmKey			 			= '<?php echo $gsmKey; ?>';
var onlineLegend			 	= '<?php echo $locale_text["GPSMAP_online_legend"]; ?>';
var yellowLegend			 	= '<?php echo $locale_text["GPSMAP_yellow_legend"]; ?>';
var offlineLegend			 	= '<?php echo $locale_text["GPSMAP_offline_legend"]; ?>';

var imeiList					= [];
var carData 					= [];
var empJobList 					= [];

var jobtooltip	 				= $("<div id='tooltip'><div class='mousehovercontent'/></div>");
var toolTipTimer 				= "";
var haveTooltip 				= false;
var custPopoverVisible 			= false;  				// Tracks the visibility of the popover
var jobPopoverVisible 			= false;  				// Tracks the visibility of the popover
var lastUpdated					= Date.now();			// Last provided UNIX timestamp to getlocations

var inputTimer;
var lastSearchString = "";
var custQueueCount = 0; 

var excelData = [];										// Variable to store data to export to excel
var excelKeys = {};										// keys to lockup in excelData

var mapGlobals 					= {};
mapGlobals.map;											//	Google map obj.
mapGlobals.markerCluster;								//	Google map marker cluster
mapGlobals.infoBubble ;									//  InfoBubble at cluster
mapGlobals.allMarkers = {};								//	Contains a list to store all markers
mapGlobals.infoWin;										//	Google infowindow object, reused for all info windows
mapGlobals.JSON_employeeList;							//	Contains a list of employees
mapGlobals.JSON_gpsTransactions;						//	Contains GPS transaction (latlng) for an employee
mapGlobals.JSON_customerList;							//	Contains a list of customers that have been requested through customer search.
mapGlobals.JSON_customerListID = new Array();			//	Contains a list of id for customers
mapGlobals.JSON_serviceUnitID = new Array();			//	Contains a list of id for serviceunits
mapGlobals.JSON_locationList = {};						//	Contains a list of car locations
mapGlobals.JSON_jobList = {};							//	Contains a list of jobs locations
mapGlobals.gpsEmployeeMarkersArray = new Array();		//	Contains employee markers that are displayed
mapGlobals.addressMarker;								//	Contains marker object from address search
mapGlobals.gpsEmpLocationMarkers = new Array();			//	Contains locations markers for an employee
mapGlobals.custSearching = false;						//	Determines if a cutomer search is in progress, used for controling enter key press behaviour
mapGlobals.currentCustomerMarker;						//	Selected customer marker obj
mapGlobals.selectedCustomer = "";						//	Selected customer in customer section
mapGlobals.selectedJobs = new Array();					//	Contains job selected in list.
mapGlobals.selectedMachines = new Array();				//	Contains machines selected in list.
mapGlobals.selectedEmployees = new Array();				//	Contains employees selected in list. Used for keeping state when refreshing map.
mapGlobals.routePolyline;								//	Polyline object for a route
mapGlobals.routeArray;									//	Contains routes

const jobStatusText = <?php echo json_encode($locale_text["JOB_STATUS"]); ?>;
const timesheetText = <?php echo json_encode($locale_text["TIMESHEET_STATUS"]); ?>;

var hoverTimeout;


//get initial data from REEFT 2.0
getEmeiList();
getEmployeeList();
getDepartmentList();

//=============================================================================
// Get a JSON list of employees with emei
//=============================================================================
function getEmeiList(){
	
	$.ajaxq('getQueue',{
		cache: false,
		url: "ajax_get_emei_list.php",
		dataType: "json",
		success: function(jsonData){
			//console.log(jsonData);
			if (jsonData["error"] != "") {
				console.log(jsonData["error"]);
			} else {
				delete jsonData["error"];
				imeiList = Object.keys(jsonData);
				mapGlobals.JSON_employeeList = jsonData;
				
				var resultHTMLEmp = "";
				
				$.each( jsonData, function( index, item ){				
					const id 			= item.id;
					const userId		= item.userId;
					const depName		= item.departmentName;
					const depCode		= item.departmentCode;
					const depId			= item.departmentId;
					const imei 			= item.imei;
					const name 			= item.name;
					const initials 		= item.initials;	
					
					resultHTMLEmp += "<li id=\"emp_"+imei+"\" class=\"list-group-item d-flex justify-content-between align-items-center listItem dep_"+depId+" isOffline d-none\" style=\"font-size: 0.9rem !important;\">("+initials+") "+name+"<span class=\"list-right d-flex align-items-center\"><span id=\"empInfo_"+imei+"\" class=\"listIconInfo me-2\"><i class=\"fa-solid fa-circle-info\"></i></span><span class=\"badge bg-danger border border-light rounded-circle\" title=\""+offlineLegend+"\">&nbsp;</span></span></li>";
					
					
				});	
				
				// employees
				$("#employeeList").html(resultHTMLEmp);

				
				// Add click event to listIconInfo
				$('#employeeList .listIconInfo').on('click', function () {
					
					event.stopPropagation();
					
					// Get the clicked icon's position
					const icon = $(this);
					
					// Customize modal content dynamically based on the clicked element
					const employeeId = $(this).closest('li').attr('id');
					const persID = employeeId.split("_");
					const imei = persID[1];
					const emp = mapGlobals.JSON_employeeList[imei];
					const location = mapGlobals.JSON_locationList[imei];
					
					const id 		= emp.id;
					const userId 	= emp.userId;
					const name 		= emp.name;
					const initials 	= emp.initials;
					const phone 	= emp.phone;
					
					if (typeof location !== "undefined" && location !== null) {
						var deviceId	= location.id;
						var lat 		= location.lat;
						var lng 		= location.lng;
					}
					const addressId	= 'addressTxt_'+imei;
					
					var labelHTML = '<div class="row">'
								+ 	'<div id="selectedEmp" class="col">'
								+ 	'(' + initials + ') ' + name ;
					if (phone != "" && phone != "null") {			
						labelHTML += '&nbsp;&nbsp;'
								+ 	'<i class="fa-light fa-phone"></i> '
								+ 	phone ;
					}
					labelHTML += 	'</div>'
								+ '</div>';
					
					labelHTML += '<div class="row">'
								+ 	'<div class="col">'
								+ 	'<span id="'+addressId+'"></span>'
								+ 	'</div>'
								+ '</div>';
								
					
					$('#empInfoModalLabel').html(labelHTML);
					$('#empInfoModal-userId').val(userId);
					$("#day-gpsContainer").html("");
					$("#period-gpsContainer").html("");
					
					if (typeof location !== "undefined" && location !== null) {
						geoCodeLatLng(lat, lng, addressId);					
						$("#empInfoModal-deviceId").val(deviceId);
					} else {
						const errmsg = '<?php echo $locale_text["GPSMAP_unknown_location"] ?>';
						$("#"+addressId).html(errmsg);
						$("#empInfoModal-deviceId").val("");
					}
					
					
					$("#empInfoModal").draggable({
						handle: ".modal-header",
						scroll: false // Prevent draggable from affecting scrolling
					});
					
					const nodata = '<?php echo $locale_text["GPSMAP_noData"] ?>';
					
					
					//TODO: get data
					getJobs(userId , "#empTodayJobContainer");
					
					// Reset
					$("#hideRouteBtn").click();
					$("#hideRouteBtn").addClass("d-none");
					$("#showRouteBtn").removeClass("d-none");

					// Prevent scroll from getting dragged along
					$('#empInfoModal-body').on('mousedown touchstart', function (e) {
						e.stopPropagation(); // Stop propagation to the draggable modal
					});

					 // Show the modal
					const modal = new bootstrap.Modal(document.getElementById('empInfoModal'), {
						backdrop: false // Disable backdrop interference
					});
					modal.show();
					
					
					//document.getElementById('offcanvasScrolling').classList.add('show');
					

									
				});
								

			}
			
		}
	});
	
}

//=============================================================================
// Get a JSON list of department 
//=============================================================================
function getDepartmentList(){
	
	$.ajaxq('getQueue',{
		cache: false,
		url: "ajax_get_department_list.php",
		dataType: "json",
		success: function(jsonData){
			//console.log(jsonData);
			if (jsonData["error"] != "") {
				console.log(jsonData["error"]);
			} else {
				delete jsonData["error"];
				
				//get departments
				var resultHTMLDep = "";
				
				$.each( jsonData, function( index, item ){				
					const id 		= item.id;
					const name 		= item.name;
					const userCount = item.userCount;
					
					resultHTMLDep += "<option value=\""+id+"\">"+name+"</option>";
					
				});
				
				// departments
				$("#depListDropDown").html(resultHTMLDep);
				$("#depListDropDown").chosen({width: "100%"});
				
				$("#jobDepListDropDown").html(resultHTMLDep);
				$("#jobDepListDropDown").chosen({width: "100%"});

				$("#jobCreateDepListDropDown").html("<option value=\"\"></option>" + resultHTMLDep);
				$("#jobCreateDepListDropDown").chosen({width: "100%", allow_single_deselect: true});

			}
			
		}
	});
	
}
//=============================================================================
// Get a JSON list of employees 
//=============================================================================
function getEmployeeList(){
	
	$.ajaxq('getQueue',{
		cache: false,
		url: "ajax_get_employee_list.php",
		dataType: "json",
		success: function(jsonData){
			//console.log(jsonData);
			if (jsonData["error"] != "") {
				console.log(jsonData["error"]);
			} else {
				delete jsonData["error"];
				
				var resultHTMLEmp = "";
				
				$.each( jsonData, function( index, item ){				
					const id 		= item.id;
					const userId	= item.userId;
					const depName	= item.departmentName;
					var depId		= item.departmentId	;
					const orgName	= item.organizationName;
					const orgId		= item.organizationId	;
					const imei 		= item.imei;
					const name 		= item.name;
					const initials 	= item.initials;
					
					if (!depId || depId == "") depId = orgId;
					
					resultHTMLEmp += "<option value=\""+userId+"\" class=\"dep_"+depId+" \">("+initials+") "+name+"</option>";
					
				});
				
				// employees
				$("#jobEmpListDropDown").html(resultHTMLEmp);
				$("#jobEmpListDropDown").chosen({width: "100%"});
					
				$("#jobCreateEmpListDropDown").html("<option class=\"allDep\" value=\"\"></option>" + resultHTMLEmp);
				$("#jobCreateEmpListDropDown").chosen({width: "100%"});
					
			}
			
		}
	});
	
}

//=============================================================================
// Create job
//=============================================================================
function jobCreate(customer){
	
		const id 		= customer.id;
		const name 		= customer.name;
		const label 	= '<?php echo $locale_text["GPSMAP_create_job"] ?>';
		
		var labelHTML = label + " <span class=\"fw-bold\">" + name + "</span>";
		
		const form = document.getElementById("jobCreateForm");
        form.reset(); // Clear all inputs, selects, and textareas

        $("#jobCreateDepListDropDown").val("").trigger("chosen:updated"); // Reset dropdown
        $("#jobCreateActTypeListDropDown").val("").trigger("chosen:updated"); // Reset dropdown
        $("#jobCreateEmpListDropDown").val("").trigger("chosen:updated"); // Reset dropdown
	
		$('#jobCreateModalLabel').html(labelHTML);
		$('#jobCreateModal-custId').val(id);
		$('#jobCreateModal-serviceunitId').val('');
		
		

		 // Show the modal
		const modal = new bootstrap.Modal(document.getElementById('jobCreateModal'), {
			backdrop: false // Disable backdrop interference
		});
		modal.show();
}


//=============================================================================
// Create job serviceunit
//=============================================================================
function jobCreateServiceunit(serviceunitID, serviceunitName){
		
		if(mapGlobals.selectedCustomer != ""){
            jobCreate(mapGlobals.selectedCustomer, "CUST");
		}
		else{
			alert("<?php echo $locale_text["ERROR_CHOOSE_CUST"]; ?>");
		}
		
		var customer = mapGlobals.selectedCustomer;
		
		const id 		= customer.id;
		const name 		= customer.name;
		const label 	= '<?php echo $locale_text["GPSMAP_create_job"] ?>';
		
		var labelHTML = label + " <span class=\"fw-bold\">" + name + " / " + serviceunitName + "</span>";
		
		const form = document.getElementById("jobCreateForm");
        form.reset(); // Clear all inputs, selects, and textareas

        $("#jobCreateDepListDropDown").val("").trigger("chosen:updated"); // Reset dropdown
        $("#jobCreateActTypeListDropDown").val("").trigger("chosen:updated"); // Reset dropdown
        $("#jobCreateEmpListDropDown").val("").trigger("chosen:updated"); // Reset dropdown
	
		$('#jobCreateModalLabel').html(labelHTML);
		$('#jobCreateModal-custId').val(id);
		$('#jobCreateModal-serviceunitId').val(serviceunitID);
		
		

		 // Show the modal
		const modal = new bootstrap.Modal(document.getElementById('jobCreateModal'), {
			backdrop: false // Disable backdrop interference
		});
		modal.show();
}

//=============================================================================
// Clear jobliste
//=============================================================================
function clearJoblist(){
	//  Hide all jobs
    $("#hideAllJobsBtn").click();
	$("#mainJobList").html("");
    $("#clearAllJobsBtn").addClass("d-none");
    $("#showAllJobsBtn").addClass("d-none");
}

//=============================================================================
// Get jobliste
//=============================================================================
function getJoblist(){
	
	$("#job-message").addClass("d-none");
	
	//  Hide all jobs
    $("#hideAllJobsBtn").click();
	
	const fromDate = $('#job-fromdateInput').val();
	const toDate = $('#job-todateInput').val();
	
	const selectedDep = $('#jobDepListDropDown').val();
	var selectedEmp = $('#jobEmpListDropDown').val();
	const selectedStatus = $('#jobStatusListDropDown').val();
	const selectedActType = $('#jobActTypeListDropDown').val();
	
	const jobGetUnassigned = $('#jobGetUnassigned').prop('checked');
	const getUnassigned = (jobGetUnassigned ? 'Y' : 'N');
	
	if (selectedEmp.length == 0 && selectedDep.length > 0) {
		// Filter out the disabled options
		var allOptions = $('#jobEmpListDropDown option');
		var nonDisabledOptions = allOptions.filter(function () {
			return !$(this).is(':disabled');
		});
		let nonDisabledValues = nonDisabledOptions.map(function () {
			return $(this).val();
		}).get();

		selectedEmp = nonDisabledValues;
	}
	
	
	if (fromDate.trim() == "") {
		$("#job-message").removeClass("d-none").html( '<?php echo $locale_text["ERROR_FROMDATE_WARNING"] ?>' );
		$('#job-fromdateInput').focus();
		return;
	}
	if (toDate.trim() == "") {
		$("job-message").removeClass("d-none").html( '<?php echo $locale_text["ERROR_TODATE_WARNING"] ?>' );
		$('#job-todateInput').focus();
		return;
	}
	
	if (toDate < fromDate) {
		$("#job-message").removeClass("d-none").html( '<?php echo $locale_text["ERROR_DATE_GREATER"] ?>' );
		$('#job-todateInput').focus();
		return;
	}
	
	parmData = 'selectedDep='+selectedDep
				+ '&selectedEmp='+selectedEmp
				+ '&selectedStatus='+selectedStatus
				+ '&selectedActType='+selectedActType
				+ '&startDate=' + fromDate
				+ '&endDate=' + toDate
				+ '&getUnassigned=' + getUnassigned
				+ '&type=**LIST**'
				;
	
	$("#jobListSpinner").removeClass("d-none");
	
	$.ajax({
		cache: false,
		url: "ajax_get_joblist.php",
		data: parmData,
		dataType: "json",
		success: function(jsonData){
			//console.log(jsonData);
			
			if (jsonData["error"] != "") {
				console.log(jsonData["error"]);
			} else {
				delete jsonData["error"];
				
				const jobList = jsonData["jobList"]; 
				const jobscheduleList = jsonData["jobscheduleList"]; 
				
				var resultCount = Object.keys(jobList).length; 
				
				if ( resultCount == 0 ) {
					var resultHTML = "<?php echo $locale_text["GPSMAP_noData"]; ?>"
				} else {
					var resultHTML = "";
					$("#showAllJobsBtn").removeClass("d-none");
					$("#clearAllJobsBtn").removeClass("d-none");
				}
				
				$.each( jobList, function( index, item ){	
					empJobList[item["jobNumber"]] = item;
					
					const id							= item["id"];
					const jobNumber						= item["jobNumber"];
					const externalJobNumber				= item["externalJobNumber"];
					const jobTagName					= item["jobTagName"];
					const activityTypeName				= item["activityTypeName"];
					const customerName					= item["customerName"];
					const responsibleName				= item["responsibleName"];
					const createdByName					= item["createdByName"];
					const isGroup						= item["isGroup"];
					const departmentName				= item["departmentName"];
					const customerCode					= item["customerCode"];
					const customerCategory				= item["customerCategory"];
					const serviceUnitCode				= item["serviceUnitCode"];
					const serviceUnitName				= item["serviceUnitName"];
					const serviceUnitSerialNumber		= item["serviceUnitSerialNumber"];
					const serviceUnitCategory			= item["serviceUnitCategory"];
					const assignedTo					= item["assignedTo"];
					const completedDateTime				= item["completedDateTime"];
					const totalScheduledWork			= item["totalScheduledWork"];
					const totalTimeLogged				= item["totalTimeLogged"];
					const clientDateTime				= item["clientDateTime"];
					const isRecurring					= item["isRecurring"];
					const isCritical					= item["isCritical"];
					const jobStatus						= item["jobStatus"];
					const contactPerson					= item["contactPerson"];
					const contactPhone					= item["contactPhone"];
					const contactEmail					= item["contactEmail"];
					const contactMobile					= item["contactMobile"];
					const shortDescription				= item["shortDescription"];
					const requisitionNumber				= item["requisitionNumber"];
					const estimatedHours				= item["estimatedHours"];
					const startDateTime					= item["startDateTime"];
					const startDateTimeLocal			= item["startDateTimeLocal"];
					const dueDateTime					= item["dueDateTime"];
					const dueDateTimeLocal				= item["dueDateTimeLocal"];
					const location						= item["location"];
					const street						= item["street"];
					const zipCode						= item["zipCode"];
					const city							= item["city"];
					const country						= item["country"];
					const longitude						= item["longitude"];
					const latitude						= item["latitude"];
					const createdAt						= item["createdAt"];
					const createdDateTime				= item["createdDateTime"];
					
					mapGlobals.JSON_jobList[jobNumber] = item;
					
					var jobStatusTxt = jobStatusText[jobStatus];
					
					var address	 	= item["location"] + " " + item["street"] + " " + item["zipCode"] + " " + item["city"]+ " " + item["country"]  ;
					address = address.replace("null", "").trim();
					
					mapGlobals.JSON_jobList[jobNumber]["address"] = address;
					
					resultHTML += "<li id=\"job_"+jobNumber+"\" class=\"list-group-item listItem jobListItem text-break text-wrap\"><span class=\"d-flex justify-content-between align-items-center\">("+jobNumber+") "+shortDescription+"<span class=\"list-right d-flex align-items-center\"><span id=\"jobInfo_"+jobNumber+"\" class=\"listIconInfo jobSearchIcon me-2\"><i class=\"fa-solid fa-circle-info\"></i></span></span></span><span>"+address+"</span></li>";
					
					
				});
				
				$("#jobListSpinner").addClass("d-none");
				$("#mainJobList").html(resultHTML);
				
				
				// Add click event to listIconInfo
				$("#mainJobList").on("mouseenter", ".listIconInfo", function () {

					const $icon = $(this);
					
					// Clear any existing timeout to avoid multiple triggers
					clearTimeout(hoverTimeout);
					
					// Check if the popover is already visible for the current icon
					if ($icon.attr("aria-describedby")) {
						return; // Popover is already shown; do nothing
					}
					
					// Dispose of any existing popover to prevent duplicates 
					$(".jobSearchIcon").not($icon).each(function() {
						$(this).popover("dispose");
					});
					
					hoverTimeout = setTimeout(() => {
					
					var jobID = $(this).attr("id").split("_");
					jobID = jobID[1];
					
					const jobUuid = empJobList[jobID]["id"]
					
					parmData = 'jobUuid='+jobUuid
						;
				
				$.ajax({
					cache: false,
					url: "ajax_get_jobdetail.php",
					data: parmData,
					dataType: "json",
					success: function(jsonDataDetail){
						//console.log(jsonDataDetail);
						
						if (jsonDataDetail["error"] != "") {
							console.log(jsonDataDetail["error"]);
						} else {
							delete jsonDataDetail["error"];
							
							const jobData = jsonDataDetail[0]; 
						
							const jobNumber					= jobData["jobNumber"];
							const jobStatus					= jobData["jobStatus"];
							const customerName				= jobData["customerName"];
							const shortDescription			= jobData["shortDescription"];
							const longDescription			= jobData["longDescription"]; 
							const activityTypeName			= jobData["activityTypeName"];
							const serviceUnitName			= jobData["serviceUnitName"];
							const serviceUnitCode			= empJobList[jobID]["serviceUnitCode"];
							const location					= jobData["location"];
							const street					= jobData["street"];
							const zipCode					= jobData["zipCode"];
							const city						= jobData["city"];
							const country					= jobData["country"];
							const contactPerson				= jobData["contactPerson"];
							const contactEmail				= jobData["contactEmail"];
							const contactMobile				= jobData["contactMobile"];
							const contactPhone				= jobData["contactPhone"];
							const assignedTo				= empJobList[jobID]["assignedTo"];
							const startDateTimeLocal		= jobData["startDateTimeLocal"];
							const dueDateTimeLocal			= jobData["dueDateTimeLocal"];
							var estimatedHours				= jobData["estimatedHours"];
							
							if (estimatedHours) {
								var hours = Math.floor(estimatedHours)
								var decimal = estimatedHours - hours;
								//check if minuttes
								if (decimal > 0) {
									var estimatedMin = Math.round(decimal*60) + "<?php echo $locale_text["GPSMAP_min_short"]; ?>";
								} else {
									var estimatedMin = "";
								}
								estimatedHours = hours + "<?php echo $locale_text["GPSMAP_hour_short"]; ?> " + estimatedMin;
							} else {
								estimatedHours = "-";
							}						
							
							var customerAddr = (location ? location + ", " : "") + (street ? street + ", " : "") + (zipCode ? zipCode + " " : "") + (city ? city + ", " : "") + (country ? country : "");
							var contactInfo = (contactEmail ? "<i class=\"fa-regular fa-envelope\"></i> " +contactEmail + ", " : "") + (contactMobile ? "<i class=\"fa-regular fa-phone\"></i> " + contactMobile + ", " : "") + (contactPhone ? "<i class=\"fa-regular fa-phone-office\"></i> " + contactPhone : "");
							
							
							var resultHTML = '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"><?php echo $locale_text["GPSMAP_description"]; ?>:</div>";
							resultHTML 		+= "<div class=\"col-9\">"+longDescription+"</div>";
							resultHTML += "</div>";
							resultHTML += '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"><?php echo $locale_text["GPSMAP_act_type"]; ?>:</div>";
							resultHTML 		+= "<div class=\"col-9\">"+activityTypeName+"</div>";
							resultHTML += "</div>";
							resultHTML += '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"><?php echo $locale_text["GPSMAP_customer"]; ?>:</div>";
							resultHTML 		+= "<div class=\"col-9\">"+customerName+"</div>";
							resultHTML += "</div>";
							resultHTML += '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"></div>";
							resultHTML 		+= "<div class=\"col-9\">"+customerAddr+"</div>";
							resultHTML += "</div>";
							if (serviceUnitName) {
								resultHTML += '<div class="row">';
								resultHTML 		+= "<div class=\"col-3 fw-bold\"><?php echo $locale_text["GPSMAP_serviceunit"]; ?>:</div>";
								resultHTML 		+= "<div class=\"col-9\">("+serviceUnitCode+") "+serviceUnitName+"</div>";
								resultHTML += "</div>";
							}
							resultHTML += '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"><?php echo $locale_text["GPSMAP_contact_person"]; ?>:</div>";
							resultHTML 		+= "<div class=\"col-9\">"+contactPerson+"</div>";
							resultHTML += "</div>";
							resultHTML += '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"></div>";
							resultHTML 		+= "<div class=\"col-9\">"+contactInfo+"</div>";
							resultHTML += "</div>";
							resultHTML += '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"><?php echo $locale_text["GPSMAP_startdate"]; ?>:</div>";
							resultHTML 		+= "<div class=\"col-9\">"+startDateTimeLocal+"</div>";
							resultHTML += "</div>";
							resultHTML += '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"><?php echo $locale_text["GPSMAP_deadline"]; ?>:</div>";
							resultHTML 		+= "<div class=\"col-9\">"+dueDateTimeLocal+"</div>";
							resultHTML += "</div>";
							resultHTML += '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"><?php echo $locale_text["GPSMAP_duration"]; ?>:</div>";
							resultHTML 		+= "<div class=\"col-9\">"+estimatedHours+"</div>";
							resultHTML += "</div>";
							resultHTML += '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"><?php echo $locale_text["GPSMAP_employees"]; ?>:</div>";
							resultHTML 		+= "<div class=\"col-9\">"+assignedTo+"</div>";
							resultHTML += "</div>";
							
							
							
							// Initialize popover with the fetched content
							$icon.popover({
								title: "<div class=\"d-flex justify-content-between fw-bold\"><div>("+jobNumber+") " + shortDescription + "</div><div>"+jobStatusText[jobStatus]+"</div></div>",
								trigger: "manual",
								placement: "right",
								html: true,
								customClass: "wide-popover600",
								content: resultHTML
							});

							// Show the popover
							$icon.popover("show");
						
						}
					},
					beforeSend: function() {
							
					},
					complete: function() {
							
					},
					error: function(xhr, status, error) {
						console.log(error);
					}
					});
					
					}, 300); // Delay in milliseconds
					
				});	
			}
		
		},
		beforeSend: function() {
			
		},
		complete: function() {
			
		},
		error: function(xhr, status, error) {
			console.log(error);
		}
	});
}

//=============================================================================
// Get jobstatus
//=============================================================================
function getJobstatus(){
	var resultHTMLStatusDrop = "";
	//resultHTMLStatusDrop += "<option value=\"0\">"+jobStatusText[0]+"</option>";
	resultHTMLStatusDrop += "<option value=\"1\" selected=\"selected\">"+jobStatusText[1]+"</option>";
	resultHTMLStatusDrop += "<option value=\"2\">"+jobStatusText[2]+"</option>";
	resultHTMLStatusDrop += "<option value=\"3\">"+jobStatusText[3]+"</option>";
	resultHTMLStatusDrop += "<option value=\"4\">"+jobStatusText[4]+"</option>";
	resultHTMLStatusDrop += "<option value=\"5\">"+jobStatusText[5]+"</option>";
	resultHTMLStatusDrop += "<option value=\"6\">"+jobStatusText[6]+"</option>";
	resultHTMLStatusDrop += "<option value=\"7\">"+jobStatusText[7]+"</option>";
	
	

	
	$("#jobStatusListDropDown").html(resultHTMLStatusDrop);
	$("#jobStatusListDropDown").chosen({width: "100%"});
	
}

//=============================================================================
// Get serviceunits
//=============================================================================
function getServiceUnitList(refID) {
	
	var customerId = mapGlobals.JSON_customerListID[refID];
	
	parmData = 'CustomerId='+customerId
				;
				
	$.ajax({
		cache: false,
		url: "ajax_get_serviceunit_list.php",
		dataType: "json",
		data: parmData,
		success: function(jsonData){
			var resultHTMLserviceunits = "";
			
			//console.log(jsonData);
			if (jsonData["error"] != "") {
				console.log(jsonData["error"]);
			} else {
				delete jsonData["error"];
				$.each( jsonData, function( index, item ){				
					const id 					= item.id;
					const relatedTechnicianName = item.relatedTechnicianName;
					const customerName			= item.customerName;
					const remarks		 		= item.remarks;
					const active 				= item.active;
					const contactName 			= item.contactName;
					const contactEmail 			= item.contactEmail;
					const contactPhone 			= item.contactPhone;
					const contactMobile 		= item.contactMobile;
					const name 					= item.name;
					const code 					= item.code;
					const serialNumber 			= item.serialNumber;
					const qrCode 				= item.qrCode;
					const country 				= item.country;
					const city	 				= item.city;
					const region 				= item.region;
					const street 				= item.street;
					const location 				= item.location;
					const zipCode 				= item.zipCode;
					const attribute				= item.attribute;
					
					mapGlobals.JSON_serviceUnitID[code] = item;
					
					if (active && index != 'error') {
						resultHTMLserviceunits += "<div class=\"row mt-2\">";
						resultHTMLserviceunits += 	"<div class=\"col listfilterRow d-flex justify-content-between align-items-center\" id=\"sunit_"+code+"\" ><span id=\"sunit_name_"+code+"\" >"+name+"</span> <span> <span id='customerJobcreateIcon' onclick='jobCreateServiceunit(\""+id+"\",\""+name+"\")' title='<?php echo $locale_text["GPSMAP_create_job"]; ?>' ><i class='fa-regular fa-calendar-circle-plus'></i>&nbsp;</span> <span id=\"sunit_name_info_"+code+"\" class='servUnitInfoIcon listIconInfo'><i class='fa-solid fa-circle-info'></i>&nbsp;</span> </span></div>";
						resultHTMLserviceunits += "</div>";	
						
					}
						
				});			
				
				$("#customerReferenceListContainer").html(resultHTMLserviceunits);
				$("#customerReferenceListContainer").removeClass("d-none");
				if (resultHTMLserviceunits != "") $("#referenceSearchWrapper").removeClass("d-none");
				
				// Attach hover handler to .listIconInfo within the search results 
				$("#customerReferenceListContainer").on("mouseenter", ".listIconInfo", function () {
					const $icon = $(this);
					
					var divId = $icon.attr('id');
					var divIdArr = divId.split("_");
					var selectedServUnit = mapGlobals.JSON_serviceUnitID[divIdArr[3]];
					
					var attributeTotal = Object.keys(selectedServUnit.attribute).length;
					
					// Dispose of any existing popover to prevent duplicates 
					$(".servUnitInfoIcon").each(function() {
						$(this).popover("dispose");
					});

					var borderRight = "";
					var colsize = "col-6";
					var popoverClass = "wide-popover300";
					
					if ( attributeTotal > 0 ) {
						borderRight = "border-end";
						colsize = "col-3";
						popoverClass = "wide-popover600";
					} 
					
					//we uses the lines in the first column to show standard information, attributes are shown in second column, but number of lines depends on how many have data
					var resultHTML = '<div class="row">';                   
					resultHTML += '<div class="'+colsize+' fw-bold"><?php echo $locale_text["GPSMAP_number"]; ?></div>';
					resultHTML += '<div class="'+colsize+' '+borderRight+'">' +  selectedServUnit.code + '</div>';
					if(attributeTotal > 0) {
						resultHTML += '<div class="col-3 fw-bold">'+selectedServUnit.attribute[0]["name"]+'</div>';
						resultHTML += '<div class="col-3">' +  (selectedServUnit.attribute[0]["attributeValueName"] ? selectedServUnit.attribute[0]["attributeValueName"] : "") + '</div>'; 
					} else {
						resultHTML += '<div class="col-3 fw-bold"></div>';
						resultHTML += '<div class="col-3"></div>';
					}
					resultHTML += "</div>";

					resultHTML += '<div class="row">';                   
					resultHTML += '<div class="'+colsize+' fw-bold"><?php echo $locale_text["GPSMAP_name"]; ?></div>';
					resultHTML += '<div class="'+colsize+' '+borderRight+'">' +  selectedServUnit.name + '</div>';
					if(attributeTotal > 1) {
						resultHTML += '<div class="col-3 fw-bold">'+selectedServUnit.attribute[1]["name"]+'</div>';
						resultHTML += '<div class="col-3">' +  (selectedServUnit.attribute[1]["attributeValueName"] ? selectedServUnit.attribute[1]["attributeValueName"] : "") + '</div>'; 
					} else {
						resultHTML += '<div class="col-3 fw-bold"></div>';
						resultHTML += '<div class="col-3"></div>';
					}
					resultHTML += "</div>";

					resultHTML += '<div class="row">';                   
					resultHTML += '<div class="'+colsize+' fw-bold"><?php echo $locale_text["GPSMAP_category"]; ?></div>';
					resultHTML += '<div class="'+colsize+' '+borderRight+'">' +  selectedServUnit.categoryName + '</div>';
					if(attributeTotal > 2) {
						resultHTML += '<div class="col-3 fw-bold">'+selectedServUnit.attribute[2]["name"]+'</div>';
						resultHTML += '<div class="col-3">' +  (selectedServUnit.attribute[2]["attributeValueName"] ? selectedServUnit.attribute[2]["attributeValueName"] : "") + '</div>'; 
					} else {
						resultHTML += '<div class="col-3 fw-bold"></div>';
						resultHTML += '<div class="col-3"></div>';
					}
					resultHTML += "</div>";

					resultHTML += '<div class="row">';                   
					resultHTML += '<div class="'+colsize+' fw-bold"><?php echo $locale_text["GPSMAP_QR"]; ?></div>';
					resultHTML += '<div class="'+colsize+' '+borderRight+'">' +  (selectedServUnit.qrCode ? selectedServUnit.qrCode : "") + '</div>';
					if(attributeTotal > 3) {
						resultHTML += '<div class="col-3 fw-bold">'+selectedServUnit.attribute[3]["name"]+'</div>';
						resultHTML += '<div class="col-3">' +  (selectedServUnit.attribute[3]["attributeValueName"] ? selectedServUnit.attribute[3]["attributeValueName"] : "") + '</div>'; 
					} else {
						resultHTML += '<div class="col-3 fw-bold"></div>';
						resultHTML += '<div class="col-3"></div>';
					}
					resultHTML += "</div>";

					resultHTML += '<div class="row">';                   
					resultHTML += '<div class="'+colsize+' fw-bold"><?php echo $locale_text["GPSMAP_location"]; ?></div>';
					resultHTML += '<div class="'+colsize+' '+borderRight+'">' +  (selectedServUnit.location ? selectedServUnit.location : "") + '</div>';
					if(attributeTotal > 4) {
						resultHTML += '<div class="col-3 fw-bold">'+selectedServUnit.attribute[4]["name"]+'</div>';
						resultHTML += '<div class="col-3">' +  (selectedServUnit.attribute[4]["attributeValueName"] ? selectedServUnit.attribute[4]["attributeValueName"] : "") + '</div>'; 
					} else {
						resultHTML += '<div class="col-3 fw-bold"></div>';
						resultHTML += '<div class="col-3"></div>';
					}
					resultHTML += "</div>";

					resultHTML += '<div class="row">';                   
					resultHTML += '<div class="'+colsize+' fw-bold"><?php echo $locale_text["GPSMAP_address"]; ?></div>';
					resultHTML += '<div class="'+colsize+' '+borderRight+'">' +  (selectedServUnit.street ? selectedServUnit.street : "") + '</div>';
					if(attributeTotal > 5) {
						resultHTML += '<div class="col-3 fw-bold">'+selectedServUnit.attribute[5]["name"]+'</div>';
						resultHTML += '<div class="col-3">' +  (selectedServUnit.attribute[5]["attributeValueName"] ? selectedServUnit.attribute[5]["attributeValueName"] : "") + '</div>'; 
					} else {
						resultHTML += '<div class="col-3 fw-bold"></div>';
						resultHTML += '<div class="col-3"></div>';
					}
					resultHTML += "</div>";

					resultHTML += '<div class="row">';                   
					resultHTML += '<div class="'+colsize+' fw-bold"><?php echo $locale_text["GPSMAP_zip_city"]; ?></div>';
					resultHTML += '<div class="'+colsize+' '+borderRight+'">' +  (selectedServUnit.zipCode ? selectedServUnit.zipCode : "") + " " +  (selectedServUnit.city ? selectedServUnit.city : "") + '</div>';
					if(attributeTotal > 6) {
						resultHTML += '<div class="col-3 fw-bold">'+selectedServUnit.attribute[6]["name"]+'</div>';
						resultHTML += '<div class="col-3">' +  (selectedServUnit.attribute[6]["attributeValueName"] ? selectedServUnit.attribute[6]["attributeValueName"] : "") + '</div>'; 
					} else {
						resultHTML += '<div class="col-3 fw-bold"></div>';
						resultHTML += '<div class="col-3"></div>';
					}
					resultHTML += "</div>";

					resultHTML += '<div class="row">';                   
					resultHTML += '<div class="'+colsize+' fw-bold"><?php echo $locale_text["GPSMAP_country"]; ?></div>';
					resultHTML += '<div class="'+colsize+' '+borderRight+'">' +  (selectedServUnit.country ? selectedServUnit.country : "") + '</div>';
					if(attributeTotal > 7) {
						resultHTML += '<div class="col-3 fw-bold">'+selectedServUnit.attribute[7]["name"]+'</div>';
						resultHTML += '<div class="col-3">' +  (selectedServUnit.attribute[7]["attributeValueName"] ? selectedServUnit.attribute[7]["attributeValueName"] : "") + '</div>'; 
					} else {
						resultHTML += '<div class="col-3 fw-bold"></div>';
						resultHTML += '<div class="col-3"></div>';
					}
					resultHTML += "</div>";

					resultHTML += '<div class="row">';                   
					resultHTML += '<div class="'+colsize+' fw-bold"><?php echo $locale_text["GPSMAP_contact_person"]; ?></div>';
					resultHTML += '<div class="'+colsize+' '+borderRight+'">' +  (selectedServUnit.contactName ? selectedServUnit.contactName : "") + '</div>';
					if(attributeTotal > 8) {
						resultHTML += '<div class="col-3 fw-bold">'+selectedServUnit.attribute[8]["name"]+'</div>';
						resultHTML += '<div class="col-3">' +  (selectedServUnit.attribute[8]["attributeValueName"] ? selectedServUnit.attribute[8]["attributeValueName"] : "") + '</div>'; 
					} else {
						resultHTML += '<div class="col-3 fw-bold"></div>';
						resultHTML += '<div class="col-3"></div>';
					}
					resultHTML += "</div>";

					resultHTML += '<div class="row">';                   
					resultHTML += '<div class="'+colsize+' fw-bold"><?php echo $locale_text["GPSMAP_phone"]; ?></div>';
					resultHTML += '<div class="'+colsize+' '+borderRight+'">' +  (selectedServUnit.contactPhone ? selectedServUnit.contactPhone : "") + '</div>';
					if(attributeTotal > 9) {
						resultHTML += '<div class="col-3 fw-bold">'+selectedServUnit.attribute[9]["name"]+'</div>';
						resultHTML += '<div class="col-3">' +  (selectedServUnit.attribute[9]["attributeValueName"] ? selectedServUnit.attribute[9]["attributeValueName"] : "") + '</div>'; 
					} else {
						resultHTML += '<div class="col-3 fw-bold"></div>';
						resultHTML += '<div class="col-3"></div>';
					}
					resultHTML += "</div>";

					resultHTML += '<div class="row">';                   
					resultHTML += '<div class="'+colsize+' fw-bold"><?php echo $locale_text["GPSMAP_cell_phone"]; ?></div>';
					resultHTML += '<div class="'+colsize+' '+borderRight+'">' +  (selectedServUnit.contactMobile ? selectedServUnit.contactMobile : "") + '</div>';
					if(attributeTotal > 10) {
						resultHTML += '<div class="col-3 fw-bold">'+selectedServUnit.attribute[10]["name"]+'</div>';
						resultHTML += '<div class="col-3">' +  (selectedServUnit.attribute[10]["attributeValueName"] ? selectedServUnit.attribute[9]["attributeValueName"] : "") + '</div>'; 
					} else {
						resultHTML += '<div class="col-3 fw-bold"></div>';
						resultHTML += '<div class="col-3"></div>';
					}
					resultHTML += "</div>";

					resultHTML += '<div class="row">';                   
					resultHTML += '<div class="'+colsize+' fw-bold"><?php echo $locale_text["GPSMAP_email"]; ?></div>';
					resultHTML += '<div class="'+colsize+' '+borderRight+'">' +  (selectedServUnit.contactEmail ? selectedServUnit.contactEmail : "") + '</div>';
					if(attributeTotal > 11) {
						resultHTML += '<div class="col-3 fw-bold">'+selectedServUnit.attribute[11]["name"]+'</div>';
						resultHTML += '<div class="col-3">' +  (selectedServUnit.attribute[11]["attributeValueName"] ? selectedServUnit.attribute[9]["attributeValueName"] : "") + '</div>'; 
					} else {
						resultHTML += '<div class="col-3 fw-bold"></div>';
						resultHTML += '<div class="col-3"></div>';
					}
					resultHTML += "</div>";
					
					if(attributeTotal > 12) {
						for(var i = 12; i < attributeTotal; i++) {
							resultHTML += '<div class="row">';                   
							resultHTML += '<div class="col-3 fw-bold"></div>';
							resultHTML += '<div class="col-3 '+borderRight+'"></div>';
							resultHTML += '<div class="col-3 fw-bold">'+selectedServUnit.attribute[i]["name"]+'</div>';
							resultHTML += '<div class="col-3">' +  (selectedServUnit.attribute[i]["attributeValueName"] ? selectedServUnit.attribute[i]["attributeValueName"] : "") + '</div>'; 
							resultHTML += "</div>";
						}
						
					}


					// Initialize popover with the fetched content
					$icon.popover({
						title: "<?php echo $locale_text["GPSMAP_info"] ?>",
						trigger: "manual",
						placement: "right",
						html: true,
						customClass: popoverClass,
						content: resultHTML
					});
					
					// Attach the event listener for 'inserted.bs.popover' before showing the popover
					$icon.on('inserted.bs.popover', function () {
						// Bind click event to each .custResultLine element within the popover
						$('.popover-body .custResultLine').on('click', function () {
							fillInMachineInfo(this.id); 
						});
					});
					
					// Show the popover
					$icon.popover("show");
					
				});
	
				
			}
		},
		beforeSend: function() {
			
		},
		complete: function() {
			
		},
		error: function(xhr, status, error) {
			console.log(error);
		}
	});	
	
}

//=============================================================================
// filter on customerReferenceList
//=============================================================================
function referenceFilter() {
    var input = document.getElementById("refFilter");
    var filter = input.value.toUpperCase();
       
    var elementsArrayRow = document.getElementsByClassName("listfilterRow");
    
    var filterHit = false;
    for(var i=0; i<elementsArrayRow.length; i++) {
        var id = elementsArrayRow[i].id; 
		var txtId = id.replace("sunit", "sunit_name");
		var txtValue = document.getElementById(txtId).innerHTML.toUpperCase();
		
        //check if any hit
        if (txtValue.toUpperCase().indexOf(filter) > -1) {
            filterHit = true;
            //show listLabel
            elementsArrayRow[i].classList.remove("d-none")
        } else {
            elementsArrayRow[i].classList.add("d-none")
        } 
    }
    
    if (!filterHit) {
        $("#refFilterResult").show();
    } else {
        $("#refFilterResult").hide();
    }
    
}

//=============================================================================
// Get activityTypes
//=============================================================================
function getActTypes(){
	
	$.ajaxq('getQueue',{
		cache: false,
		url: "ajax_get_activitytype_list.php",
		dataType: "json",
		success: function(jsonData){
			var resultHTMLActTypesDrop = "";
			
			//console.log(jsonData);
			if (jsonData["error"] != "") {
				console.log(jsonData["error"]);
			} else {
				delete jsonData["error"];
				$.each( jsonData, function( index, item ){				
					const id 				= item.id;
					const name 				= item.name;
					
					resultHTMLActTypesDrop += "<option value=\""+id+"\">"+ name +"</option>";
						
				});			
				
				$("#jobActTypeListDropDown").html(resultHTMLActTypesDrop);
				$("#jobActTypeListDropDown").chosen({width: "100%"});
				
				$("#jobCreateActTypeListDropDown").html("<option value=\"\"></option>" + resultHTMLActTypesDrop);
				$("#jobCreateActTypeListDropDown").chosen({width: "100%", allow_single_deselect: true});
			}
		},
		beforeSend: function() {
			
		},
		complete: function() {
			
		},
		error: function(xhr, status, error) {
			console.log(error);
		}
	});	
	
}

//=============================================================================
// Get users Jobs 
//=============================================================================
function getJobs(userId, container) {
	
	if (container == "#empTodayJobContainer") { 
		var today = new Date();
		var tomorrow = new Date(today);
		tomorrow.setDate(tomorrow.getDate() + 1);
		var startDate = today.getDate() + '-' + (today.getMonth() + 1) +'-' + today.getFullYear() + ' 00:00:00';
		var endDate = tomorrow.getDate() + '-' + (tomorrow.getMonth() + 1) +'-' + tomorrow.getFullYear() + ' 00:00:00';
	} else if (container == "#day-JobContainer") {
		const selectedDate = $('#day-dateInput').val();
		var nextDate = new Date(selectedDate);
		var startDate = nextDate.getDate() + '-' + (nextDate.getMonth() + 1) +'-' + nextDate.getFullYear() + ' 00:00:00';
		nextDate.setDate(nextDate.getDate() + 1);
		var endDate = nextDate.getDate() + '-' + (nextDate.getMonth() + 1) +'-' + nextDate.getFullYear() + ' 00:00:00';
	} else {
		var startDate = "";
		var endDate = "";
	}
	
	parmData = 'userId='+userId
				+ '&startDate=' + startDate
				+ '&endDate=' + endDate
				+ '&type=**USER**'
				;
				
	$.ajax({
		cache: false,
		url: "ajax_get_joblist.php",
		data: parmData,
		dataType: "json",
		success: function(jsonData){
			//console.log(container);
			//console.log(jsonData);
			
			if (jsonData["error"] != "") {
				console.log(jsonData["error"]);
			} else {
				delete jsonData["error"];
				
				const jobList = jsonData["jobList"]; 
				const jobscheduleList = jsonData["jobscheduleList"]; 
				
				var resultCount = Object.keys(jobList).length; 
				
				if ( resultCount == 0 ) {
					var resultHTML = "<?php echo $locale_text["GPSMAP_noData"]; ?>"
				} else {					
					var resultHTML = "<div id=\"empTodayJobList\" class=\"overflow-y-auto overflow-x-hidden\" style=\"max-height: 150px;\">";
					resultHTML += '<div class="row sticky-top border-bottom fw-bold bg-body-secondary opacity-100 bg-white">';
					resultHTML += '<div class="col-2 text-break text-wrap"><?php echo $locale_text["GPSMAP_job"]; ?></div>';
					resultHTML += '<div class="col-2 text-break text-wrap"><?php echo $locale_text["GPSMAP_customer"]; ?></div>';
					resultHTML += '<div class="col-3 text-break text-wrap"><?php echo $locale_text["GPSMAP_address"]; ?></div>';
					resultHTML += '<div class="col-3 text-break text-wrap"><?php echo $locale_text["GPSMAP_duration"]; ?></div>';
					resultHTML += '<div class="col-2 text-break text-wrap"></div>';
					resultHTML += "</div>";
				}
				
				$.each( jobList, function( index, item ){	
					empJobList[item["jobNumber"]] = item;
					
					const id							= item["id"];
					const jobNumber						= item["jobNumber"];
					const externalJobNumber				= item["externalJobNumber"];
					const jobTagName					= item["jobTagName"];
					const activityTypeName				= item["activityTypeName"];
					const customerName					= item["customerName"];
					const responsibleName				= item["responsibleName"];
					const createdByName					= item["createdByName"];
					const isGroup						= item["isGroup"];
					const departmentName				= item["departmentName"];
					const customerCode					= item["customerCode"];
					const customerCategory				= item["customerCategory"];
					const serviceUnitCode				= item["serviceUnitCode"];
					const serviceUnitName				= item["serviceUnitName"];
					const serviceUnitSerialNumber		= item["serviceUnitSerialNumber"];
					const serviceUnitCategory			= item["serviceUnitCategory"];
					const assignedTo					= item["assignedTo"];
					const completedDateTime				= item["completedDateTime"];
					const totalScheduledWork			= item["totalScheduledWork"];
					const totalTimeLogged				= item["totalTimeLogged"];
					const clientDateTime				= item["clientDateTime"];
					const isRecurring					= item["isRecurring"];
					const isCritical					= item["isCritical"];
					const jobStatus						= item["jobStatus"];
					const contactPerson					= item["contactPerson"];
					const contactPhone					= item["contactPhone"];
					const contactEmail					= item["contactEmail"];
					const contactMobile					= item["contactMobile"];
					const shortDescription				= item["shortDescription"];
					const requisitionNumber				= item["requisitionNumber"];
					const estimatedHours				= item["estimatedHours"];
					const startDateTime					= item["startDateTime"];
					const startDateTimeLocal			= item["startDateTimeLocal"];
					const dueDateTime					= item["dueDateTime"];
					const dueDateTimeLocal				= item["dueDateTimeLocal"];
					const location						= item["location"];
					const street						= item["street"];
					const zipCode						= item["zipCode"];
					const city							= item["city"];
					const country						= item["country"];
					const createdAt						= item["createdAt"];
					const createdDateTime				= item["createdDateTime"];
					
					var jobStatusTxt = jobStatusText[jobStatus];
					
					var address	 	= item["location"] + " " + item["street"] + " " + item["zipCode"] + " " + item["city"]+ " " + item["country"]  ;
					address = address.replace("null", "").trim();
					
					var jobschedules = jobscheduleList[jobNumber];
					
					var scheduleHTML = "";
					$.each( jobschedules, function( index2, schedule ){
						const startDateTimeLocalSchedule	= schedule["startDateTimeLocal"];
						const durationSchedule				= schedule["duration"];;
						
						var durationFormatted = getFormattedMinutes(durationSchedule*60);
						var newline = "<br>";
						if (scheduleHTML == "") newline = ""; 
						
						scheduleHTML += newline + "" + startDateTimeLocalSchedule + " (" + durationFormatted + ")" ;
						
					});
					
					resultHTML += '<div class="row border-bottom">';
					resultHTML += '<div class="col-2 text-break text-wrap">('+jobNumber+') '+shortDescription+'</div>';
					resultHTML += '<div class="col-2 text-break text-wrap">'+customerName+'</div>';
					resultHTML += '<div class="col-3 text-break text-wrap">'+address+'</div>';
					resultHTML += '<div class="col-3 text-break text-wrap">'+scheduleHTML+'</div>';
					resultHTML += '<div id="jobIcons_'+jobNumber+'" class="col-2 text-break text-wrap"><span class=\"jobSearchIcon listIconInfo me-2\"><i class=\"fa-solid fa-circle-info\"></i></span>';
					if (container == "#day-JobContainer") {
						resultHTML += '&nbsp&nbsp<input type="checkbox" class="historyMenuPrint printJob" id="printJob_'+id+'" name="printJob_'+id+'" value="yes" title="<?php echo $locale_text["GPSMAP_print"]; ?>">';
					}
					resultHTML += "</div>";
					resultHTML += "</div>";
					
				});
			
				$(container).html(resultHTML);
				
				// Add click event to listIconInfo
				$(container).on("mouseenter", ".listIconInfo", function () {

					const $icon = $(this);
					
					// Dispose of any existing popover to prevent duplicates 
					$(".jobSearchIcon").each(function() {
						$(this).popover("dispose");
					});
					
					var divId = $icon.parent().attr('id');
					var divIdArr = divId.split("_");
					const id = divIdArr[1];
					const jobUuid = empJobList[id]["id"]
					
					parmData = 'jobUuid='+jobUuid
						;
				
				$.ajax({
					cache: false,
					url: "ajax_get_jobdetail.php",
					data: parmData,
					dataType: "json",
					success: function(jsonDataDetail){
						//console.log(jsonDataDetail);
						
						if (jsonDataDetail["error"] != "") {
							console.log(jsonDataDetail["error"]);
						} else {
							delete jsonDataDetail["error"];
							
							const jobData = jsonDataDetail[0]; 
						
							const jobNumber					= jobData["jobNumber"];
							const jobStatus					= jobData["jobStatus"];
							const customerName				= jobData["customerName"];
							const shortDescription			= jobData["shortDescription"];
							const longDescription			= jobData["longDescription"]; 
							const activityTypeName			= jobData["activityTypeName"];
							const serviceUnitName			= jobData["serviceUnitName"];
							const serviceUnitCode			= empJobList[id]["serviceUnitCode"];
							const location					= jobData["location"];
							const street					= jobData["street"];
							const zipCode					= jobData["zipCode"];
							const city						= jobData["city"];
							const country					= jobData["country"];
							const contactPerson				= jobData["contactPerson"];
							const contactEmail				= jobData["contactEmail"];
							const contactMobile				= jobData["contactMobile"];
							const contactPhone				= jobData["contactPhone"];
							const assignedTo				= empJobList[id]["assignedTo"];
							const startDateTimeLocal		= jobData["startDateTimeLocal"];
							const dueDateTimeLocal			= jobData["dueDateTimeLocal"];
							var estimatedHours				= jobData["estimatedHours"];
							
							if (estimatedHours) {
								var hours = Math.floor(estimatedHours)
								var decimal = estimatedHours - hours;
								//check if minuttes
								if (decimal > 0) {
									var estimatedMin = Math.round(decimal*60) + "<?php echo $locale_text["GPSMAP_min_short"]; ?>";
								} else {
									var estimatedMin = "";
								}
								estimatedHours = hours + "<?php echo $locale_text["GPSMAP_hour_short"]; ?> " + estimatedMin;
							} else {
								estimatedHours = "-";
							}						
							
							var customerAddr = (location ? location + ", " : "") + (street ? street + ", " : "") + (zipCode ? zipCode + " " : "") + (city ? city + ", " : "") + (country ? country : "");
							var contactInfo = (contactEmail ? "<i class=\"fa-regular fa-envelope\"></i> " +contactEmail + ", " : "") + (contactMobile ? "<i class=\"fa-regular fa-phone\"></i> " + contactMobile + ", " : "") + (contactPhone ? "<i class=\"fa-regular fa-phone-office\"></i> " + contactPhone : "");
							
							
							var resultHTML = '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"><?php echo $locale_text["GPSMAP_description"]; ?>:</div>";
							resultHTML 		+= "<div class=\"col-9\">"+longDescription+"</div>";
							resultHTML += "</div>";
							resultHTML += '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"><?php echo $locale_text["GPSMAP_act_type"]; ?>:</div>";
							resultHTML 		+= "<div class=\"col-9\">"+activityTypeName+"</div>";
							resultHTML += "</div>";
							resultHTML += '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"><?php echo $locale_text["GPSMAP_customer"]; ?>:</div>";
							resultHTML 		+= "<div class=\"col-9\">"+customerName+"</div>";
							resultHTML += "</div>";
							resultHTML += '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"></div>";
							resultHTML 		+= "<div class=\"col-9\">"+customerAddr+"</div>";
							resultHTML += "</div>";
							if (serviceUnitName) {
								resultHTML += '<div class="row">';
								resultHTML 		+= "<div class=\"col-3 fw-bold\"><?php echo $locale_text["GPSMAP_serviceunit"]; ?>:</div>";
								resultHTML 		+= "<div class=\"col-9\">("+serviceUnitCode+") "+serviceUnitName+"</div>";
								resultHTML += "</div>";
							}
							resultHTML += '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"><?php echo $locale_text["GPSMAP_contact_person"]; ?>:</div>";
							resultHTML 		+= "<div class=\"col-9\">"+contactPerson+"</div>";
							resultHTML += "</div>";
							resultHTML += '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"></div>";
							resultHTML 		+= "<div class=\"col-9\">"+contactInfo+"</div>";
							resultHTML += "</div>";
							resultHTML += '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"><?php echo $locale_text["GPSMAP_startdate"]; ?>:</div>";
							resultHTML 		+= "<div class=\"col-9\">"+startDateTimeLocal+"</div>";
							resultHTML += "</div>";
							resultHTML += '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"><?php echo $locale_text["GPSMAP_deadline"]; ?>:</div>";
							resultHTML 		+= "<div class=\"col-9\">"+dueDateTimeLocal+"</div>";
							resultHTML += "</div>";
							resultHTML += '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"><?php echo $locale_text["GPSMAP_duration"]; ?>:</div>";
							resultHTML 		+= "<div class=\"col-9\">"+estimatedHours+"</div>";
							resultHTML += "</div>";
							resultHTML += '<div class="row">';
							resultHTML 		+= "<div class=\"col-3 fw-bold\"><?php echo $locale_text["GPSMAP_employees"]; ?>:</div>";
							resultHTML 		+= "<div class=\"col-9\">"+assignedTo+"</div>";
							resultHTML += "</div>";
							
							
							
							// Initialize popover with the fetched content
							$icon.popover({
								title: "<div class=\"d-flex justify-content-between fw-bold\"><div>("+jobNumber+") " + shortDescription + "</div><div>"+jobStatusText[jobStatus]+"</div></div>",
								trigger: "manual",
								placement: "right",
								html: true,
								customClass: "wide-popover600",
								content: resultHTML
							});
							
							// Attach the event listener for 'inserted.bs.popover' before showing the popover
							$icon.on('inserted.bs.popover', function () {
								// Bind click event to each .custResultLine element within the popover
								$('.popover-body .custResultLine').on('click', function () {
									fillInMachineInfo(this.id); 
								});
							});
							
							// Show the popover
							$icon.popover("show");
						
						}
					},
					beforeSend: function() {
							
					},
					complete: function() {
							
					},
					error: function(xhr, status, error) {
						console.log(error);
					}
					});
					
					
					
				});	
			}
		
		},
		beforeSend: function() {
			
		},
		complete: function() {
			
		},
		error: function(xhr, status, error) {
			console.log(error);
		}
	});
}

//=============================================================================
// Get timelogs
//=============================================================================
function getTimelogs(userId){
	const selectedDate = $('#day-dateInput').val();
	
	var nextDate = new Date(selectedDate);
	var startDate = nextDate.getDate() + '-' + (nextDate.getMonth() + 1) +'-' + nextDate.getFullYear() + ' 00:00:00';
	nextDate.setDate(nextDate.getDate() + 1);
	var endDate = nextDate.getDate() + '-' + (nextDate.getMonth() + 1) +'-' + nextDate.getFullYear() + ' 23:59:59';

	parmData = 'userId='+userId
				+ '&startDate=' + startDate
				+ '&endDate=' + endDate
				;
	
	$.ajax({
		cache: false,
		url: "ajax_get_timelog.php",
		data: parmData,
		dataType: "json",
		success: function(jsonData){
			//console.log(jsonData);
			if (jsonData["error"] != "") {
				console.log(jsonData["error"]);
			} else {
				delete jsonData["error"];
				
				var resultCount = Object.keys(jsonData).length; 
				
				if ( resultCount == 0 ) {
					var resultHTML = "<?php echo $locale_text["GPSMAP_noData"]; ?>"
				} else {					
					var resultHTML = 	"<div id=\"day-timesheetContainer-data\" class=\"overflow-y-auto overflow-x-hidden\" style=\"max-height: 150px;\">";
					
					resultHTML += '<div class="row sticky-top border-bottom fw-bold bg-body-secondary opacity-100 bg-white">';
					resultHTML += '<div class="col-2 text-break text-wrap"><?php echo $locale_text["GPSMAP_job"]; ?></div>';
					resultHTML += '<div class="col-2 text-break text-wrap"><?php echo $locale_text["GPSMAP_customer"]; ?></div>';
					resultHTML += '<div class="col-3 text-break text-wrap"><?php echo $locale_text["GPSMAP_address"]; ?></div>';
					resultHTML += '<div class="col-2 text-break text-wrap"><?php echo $locale_text["GPSMAP_salary_type"]; ?></div>';
					resultHTML += '<div class="col-2 text-break text-wrap"><?php echo $locale_text["GPSMAP_duration"]; ?></div>';
					resultHTML += '<div class="col-1 text-break text-wrap"></div>';
					resultHTML += "</div>";
					
					
					$.each( jsonData, function( index, item ){	
						
						const id 			= item["id"];
						const jobNumber 	= item["jobNumber"];
						const jobName 		= item["jobName"];
						const customerName 	= item["customerName"];
						var address	 	= item["location"] + " " + item["street"] + " " + item["zipCode"] + " " + item["city"]+ " " + item["country"]  ;
						address = address.replace("null", "").trim();
						const salaryTypeName 	= item["salaryTypeName"];
						const statusName		= item["statusName"];
						const sorttype			= item["sorttype"];
						const unit				= item["unit"];
						const unitValue			= item["unitValue"];
						
						var hours = "";  
						
						if (!unit) {
							const EndTimeLocal 		= item[sorttype+"EndTimeLocal"];
							const StartTimeLocal 	= item[sorttype+"StartTimeLocal"];
							
							const endStamp = Math.round( Date.parse( EndTimeLocal ) / 1000);
							const startStamp = Math.round( Date.parse( StartTimeLocal ) / 1000);
							
							var EndTimeLocalArr = EndTimeLocal.split(" ");
							var EndHourLocalArr = EndTimeLocalArr[1].split(":");
							var StartTimeLocalArr = StartTimeLocal.split(" ");
							var StartHourLocalArr = StartTimeLocalArr[1].split(":");
							
							hours = "<br>("+StartHourLocalArr[0]+":"+StartHourLocalArr[1]+ " - " + EndHourLocalArr[0]+":"+EndHourLocalArr[1] + ")";
							
							var diff = timeDifference(endStamp, startStamp);
							var duration = getFormattedMinutes(diff);
							
						} else {
							var duration = unitValue + " " + unit; 
						}
						resultHTML += '<div class="row border-bottom">';
						resultHTML += '<div class="col-2 text-break text-wrap">('+jobNumber+') '+jobName+'</div>';
						resultHTML += '<div class="col-2 text-break text-wrap">'+customerName+'</div>';
						resultHTML += '<div class="col-3 text-break text-wrap">'+address+'</div>';
						resultHTML += '<div class="col-2 text-break text-wrap">'+salaryTypeName+' ('+statusName+')</div>';
						resultHTML += '<div class="col-2 text-break text-wrap">'+duration+hours+'</div>';
						resultHTML += '<div class="col-1 text-break text-wrap"><input type="checkbox" class="historyMenuPrint printScheme" id="printScheme_'+id+'" name="printScheme_'+id+'" value="yes" title="<?php echo $locale_text["GPSMAP_print"]; ?>"></div>';
						resultHTML += "</div>";
					});
					
					resultHTML += "</div>";
				
				}
				
				$("#day-timesheetContainer").html(resultHTML);
			}
		
		},
		beforeSend: function() {
			
		},
		complete: function() {
			
		},
		error: function(xhr, status, error) {
			console.log(error);
		}
	});
}

//=============================================================================
// Get days data
//=============================================================================
function getDayData(){
		getRoute('*DAY*');
		
		var userId = $("#empInfoModal-userId").val();
		
		getJobs(userId, "#day-JobContainer");
		getTimelogs(userId);

}

//=============================================================================
// Get Route
//=============================================================================
function getRoute(type){
	
	var parmData = "";
	$("#modal-message").addClass("d-none");
	$("#hideRouteBtn").click();
	$("#printGPSTransactionsAllCheck").prop('checked', false); // Unchecks it
	
	if (type == '*DAY*') {
		
		const selectedDate = $('#day-dateInput').val();
		const deviceId =$("#empInfoModal-deviceId").val();
		
		if (selectedDate.trim() == "") {
			$("#modal-message").removeClass("d-none").html( '<?php echo $locale_text["ERROR_DATE_WARNING"] ?>' );
			$('#day-dateInput').focus();
			return;
		}
		
		parmData = 'from_date=' + selectedDate
					+ '&to_date=' + selectedDate
					+ '&device_id=' + deviceId
				;
		
	} else if (type == '*PERIOD*') {
		
		const fromDate = $('#period-fromdateInput').val();
		const toDate = $('#period-todateInput').val();
		const deviceId =$("#empInfoModal-deviceId").val();
		
		if (fromDate.trim() == "") {
			$("#modal-message").removeClass("d-none").html( '<?php echo $locale_text["ERROR_FROMDATE_WARNING"] ?>' );
			$('#period-fromdateInput').focus();
			return;
		}
		if (toDate.trim() == "") {
			$("#modal-message").removeClass("d-none").html( '<?php echo $locale_text["ERROR_TODATE_WARNING"] ?>' );
			$('#period-todateInput').focus();
			return;
		}
		
		if (toDate < fromDate) {
			$("#modal-message").removeClass("d-none").html( '<?php echo $locale_text["ERROR_DATE_GREATER"] ?>' );
			$('#period-todateInput').focus();
			return;
		}
		
		const date1 = new Date(fromDate);
		const date2 = new Date(toDate);
		const diffTime = Math.abs(date2 - date1);
		const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24)); 
		
		if (diffDays > 31) {
			$("#modal-message").removeClass("d-none").html( '<?php echo $locale_text["ERROR_PERIOD"] ?>' );
			$('#period-todateInput').focus();
			return;
		}
		
		parmData = 'from_date=' + fromDate
					+ '&to_date=' + toDate
					+ '&device_id=' + deviceId
				;
	}
	
	excelKeys = {};	
	
	
	$.ajaxq('historyQueue',{
		url: 'gps_tracker_get_history.php',
		type: 'GET',
		data: parmData,
		dataType: 'json',
		success: function(jsonData) {
			
			if (jsonData["error"] != "") {
				console.log(jsonData["error"]);
			} 	
			
			mapGlobals.JSON_gpsTransactions = jsonData.data;
			
			var routeArray = new Array();       // holds route info      
            var totalDistance = 0;				
            var totalDuration = 0;             
            var curDistance = 0;
            var prevTrans = {};
            var curTrans = {};
            var lastMoveTrans = {};
            var firstPauseTrans = {};
			var currentRoute = {};
            var moving = 'N';
            var shortstop = 'N';
			
			excelData = [];
			excelKeys = {};
			
            for(i in mapGlobals.JSON_gpsTransactions) {
                curTrans = mapGlobals.JSON_gpsTransactions[i];
				
				//  Calculate route distance
				totalDistance += curTrans["distance"];
				curDistance += curTrans["distance"];
				
				// speed is used to decide if we are on the move or not
				// a route is from A to B ignoring stops under 5 min 
				
				if (curTrans["speed"] > 0) {
					if (moving == 'N') {
						currentRoute["startTime"] 		= curTrans["time"];
						currentRoute["startTimeStamp"] 	= curTrans["timestamp"];  //stamp in seconds
						currentRoute["startLat"] 		= curTrans["latitude"];
						currentRoute["startLon"] 		= curTrans["longitude"];
						currentRoute["driving"] 		= 'Y';
						moving = 'Y';
					}
					shortstop = 'N';
					lastMoveTrans = curTrans;
				} else {
					if (moving == 'Y') {
						if (timeDifference(curTrans["timestamp"],lastMoveTrans["timestamp"]) >= 300) {	// More than 5 min
							moving = 'N';
							if (shortstop == 'Y') {
								currentRoute["endTime"] 		= firstPauseTrans["time"];
								currentRoute["endTimeStamp"] 	= firstPauseTrans["timestamp"];
								currentRoute["endLat"] 			= firstPauseTrans["latitude"];
								currentRoute["endLon"] 			= firstPauseTrans["longitude"];
								currentRoute["distance"] 		= curDistance;
								currentRoute["duration"]		= timeDifference(firstPauseTrans["timestamp"],currentRoute["startTimeStamp"]);
							} else {
								currentRoute["endTime"] 		= curTrans["time"];
								currentRoute["endTimeStamp"] 	= curTrans["timestamp"];
								currentRoute["endLat"] 			= curTrans["latitude"];
								currentRoute["endLon"] 			= curTrans["longitude"];
								currentRoute["distance"] 		= curDistance;
								currentRoute["duration"]		= timeDifference(curTrans["timestamp"],currentRoute["startTimeStamp"]);
							}
							currentRoute["driving"] 			= 'N';
							routeArray.push(currentRoute);
							
							totalDuration += currentRoute["duration"];
							
							//Reset
							currentRoute = {};
							curDistance = 0;
							shortstop = 'N';
						} else if (shortstop == 'N') {
							shortstop = 'Y';
							firstPauseTrans = curTrans;
						}
					}
				}
				
				prevTrans = curTrans;
            }
			
			if (!jQuery.isEmptyObject(currentRoute)) {
				if (shortstop == 'Y') {
								currentRoute["endTime"] 		= firstPauseTrans["time"];
								currentRoute["endTimeStamp"] 	= firstPauseTrans["timestamp"];
								currentRoute["endLat"] 			= firstPauseTrans["latitude"];
								currentRoute["endLon"] 			= firstPauseTrans["longitude"];
								currentRoute["distance"] 		= curDistance;
								currentRoute["duration"]		= timeDifference(firstPauseTrans["timestamp"],currentRoute["startTimeStamp"]);
								currentRoute["driving"] 		= 'N';
							} else {
								currentRoute["endTime"] 		= curTrans["time"];
								currentRoute["endTimeStamp"] 	= curTrans["timestamp"];
								currentRoute["endLat"] 			= curTrans["latitude"];
								currentRoute["endLon"] 			= curTrans["longitude"];
								currentRoute["distance"] 		= curDistance;
								currentRoute["duration"]		= timeDifference(curTrans["timestamp"],currentRoute["startTimeStamp"]);
								currentRoute["driving"] 		= 'Y';
							}
							
							routeArray.push(currentRoute);
							
							totalDuration += currentRoute["duration"];
			}

			mapGlobals.routeArray = routeArray;
			
			//  Set html            
            var html = "";
			
			if(routeArray.length > 0){  //  If result
			
				$("#getrouteBtnDay").addClass("col-disabled");
				$("#getrouteBtnPeriod").addClass("col-disabled");
				$("#printCol").addClass("col-disabled");
				$("#printExcelCol").addClass("col-disabled");
				$("#printPeriodCol").addClass("col-disabled");
			
				var excelHeader =  {};
				excelHeader["start"]        	= "<?php echo $locale_text["GPSMAP_start"]; ?>";
				excelHeader["startLocation"]    = "";
				excelHeader["stop"]        		= "<?php echo $locale_text["GPSMAP_stop"]; ?>";
				excelHeader["stopLocation"]    	= "";
				excelHeader["distance"]    	= "<?php echo $locale_text["GPSMAP_distance"]; ?>";
				excelHeader["duration"]    	= "<?php echo $locale_text["GPSMAP_duration"]; ?>";
				excelHeader["durationRaw"]    	= "<?php echo $locale_text["GPSMAP_duration"]; ?>";
				excelData.push(excelHeader);
			
				html += "<div class=\"border\">";
				
				if (type == "*PERIOD*") {
					html += 	"<div id=\"period-gpsContainer-data\" class=\"overflow-y-auto overflow-x-hidden\" style=\"max-height: 300px;\">";
				} else {
					html += 	"<div id=\"day-gpsContainer-data\" class=\"overflow-y-auto overflow-x-hidden\" style=\"max-height: 150px;\">";
				}
				
				//header
				html += 	"<div class=\"row bg-body-secondary sticky-top border-bottom fw-bold opacity-100 bg-white\">";
				html += 		"<div class=\"col-4 text-break text-wrap\"><?php echo $locale_text["GPSMAP_start"]; ?></div>";
				html += 		"<div class=\"col-4 text-break text-wrap\"><?php echo $locale_text["GPSMAP_stop"]; ?></div>";
				html += 		"<div class=\"col-2 text-break text-wrap\"><?php echo $locale_text["GPSMAP_distance"]; ?></div>";
				html += 		"<div class=\"col-2 text-break text-wrap\"><?php echo $locale_text["GPSMAP_duration"]; ?></div>";
				html += 	"</div>";
				

                for(i in routeArray){
					
					
					if (type == "*PERIOD*") {
                        var rowId = "routePeriod_" + i;
                        var routeStartId = "routeStartPeriod_" + i;
                        var routeEndId = "routeEndPeriod_" + i;
                        var printRouteChkBox = "";
                    } else {
                        var rowId = "route_" + i;
                        var routeStartId = "routeStart_" + i;
                        var routeEndId = "routeEnd_" + i;
                        var printRouteChkBox = "<input type=\"checkbox\" class=\"historyMenuPrint inSummation printRoute\" id=\"printRoute_"+ i +"\" name=\"printRoute_"+ i +"\" onclick='recalculateSummations();' value=\"yes\" title=\"<?php echo $locale_text["GPSMAP_print"]; ?>\">";
                    }
					
					if (routeArray[i]["driving"] == 'Y') {
						var truckIcon = '<span title="<?php echo $locale_text["GPSMAP_still_driving"]; ?>"><i class="fa-sharp fa-thin fa-truck-fast"></i></span>';
					} else {
						var truckIcon = '';
					}
					
					
					// row - stopped
					if (i != 0) {
						
						var stopDuration = timeDifference(routeArray[i-1]["endTimeStamp"],routeArray[i]["startTimeStamp"]);
						
						html += "<div class=\"row bg-body-secondary border-bottom\">";
						html += 	"<div class=\"col-4 text-break text-wrap\"><?php echo $locale_text["GPSMAP_stopped"]; ?></div>";
						html += 	"<div class=\"col-4 text-break text-wrap\"></div>";
						html += 	"<div class=\"col-2 text-break text-wrap\"></div>";
						if (type == '*DAY*') {
							html += 	"<div class=\"col-2 text-break text-wrap\">";
							html += 		"<div class=\"row gx-0\">";
							html += 			"<div class=\"col-7 text-break text-wrap\">"+getFormattedMinutes(stopDuration)+"</div>";
							html +=   			"<div class=\"col-5 text-break text-wrap text-end\">";
							html +=					"<span id=\"hideRoute_"+ i +"\" onclick=\"hideRoutePart("+i+")\" class=\"listIcon listIconHideRoute cursorPointer invisible\" title=\"<?php echo $locale_text["GPSMAP_hideRoute"]; ?>\" ><i class=\"fad fa-route fa-fw\"></i></span>";
							html +=				"&nbsp;&nbsp;<input type=\"checkbox\" class=\"historyMenuPrint printRoute\" id=\"printStop_" + i + "\" name=\"printStop_" + i + "\" value=\"yes\" title=\"<?php echo $locale_text["GPSMAP_print"]; ?>\">&nbsp&nbsp;";
							html +=				"</div>";
							html +=			"</div>";
							html += 	"</div>";
						} else {
							html += 	"<div class=\"col-2 text-break text-wrap\">"+getFormattedMinutes(stopDuration)+"</div>";
						}
						html += "</div>";
						
						var excelRow =  {};
						excelRow["start"]        	= "<?php echo $locale_text["GPSMAP_stopped"]; ?>";
						excelRow["startLocation"]   = "";
						excelRow["stop"]        	= "";
						excelRow["stopLocation"]    = "";
						excelRow["distance"]    	= "";
						excelRow["duration"]    	= getFormattedMinutes(stopDuration);
						excelRow["durationRaw"]    	= stopDuration;
						excelData.push(excelRow);
					}
					
					
					const routeStartTimeArr = routeArray[i]["startTime"].split(" ");
					const routeEndTimeArr = routeArray[i]["endTime"].split(" ");
					
					const routeStartTimeFormatted = routeStartTimeArr[0] + "<br> " + routeStartTimeArr[1];
					const routeEndTimeFormatted = routeEndTimeArr[0] + "<br> " + routeEndTimeArr[1];
					
					// row - driving
					html += "<div class=\"row border-bottom\">";
					html += 	"<div class=\"col-4 text-break text-wrap\">";
					html += 		"<div class=\"row gx-0\">";
					html += 			"<div class=\"col-5 text-break text-wrap\">"+routeStartTimeFormatted+"</div>";
					html += 			"<div class=\"col-7 text-break text-wrap\"><div id=\""+ routeStartId +"\" class=\"spinner-border spinner-border-sm word-wrap\" aria-hidden=\"true\"></div></div>";
					html += 		"</div>";
					html += 	"</div>";
					html += 	"<div class=\"col-4 text-break text-wrap\">";
					html += 		"<div class=\"row gx-0\">";
					html += 			"<div class=\"col-5 text-break text-wrap\">"+routeEndTimeFormatted+"</div>";
					html += 			"<div class=\"col-7 text-break text-wrap\"><div id=\""+ routeEndId +"\" class=\"spinner-border spinner-border-sm word-wrap\" aria-hidden=\"true\"></div></div>";
					html += 		"</div>";
					html += 	"</div>";
					html += 	"<div class=\"col-2 text-break text-wrap\">"+routeArray[i]["distance"].toFixed(2)+ " " + truckIcon + "<input  id=\"distance_" + i + "\" class=\"d-none\" value=\"" + routeArray[i]["distance"] +  "\" /></div>";
					if (type == '*DAY*') {
						html += 	"<div class=\"col-2 text-break text-wrap\">";
						html += 		"<div class=\"row gx-0\">";
						html += 			"<div class=\"col-7 text-break text-wrap\">"+getFormattedMinutes(routeArray[i]["duration"]) + "<input  id=\"duration_" + i + "\" class=\"d-none\" value=\"" + routeArray[i]["duration"] +  "\" /></div>";
						html +=   			"<div class=\"col-5 text-break text-wrap text-end\">";
						html +=				"<span id=\"showRoute_"+ i +"\" onclick=\"showRoutePart("+i+")\" class=\"listIcon listIconShowRoute cursorPointer\" title=\"<?php echo $locale_text["GPSMAP_showRoute"]; ?>\" ><i class=\"fad fa-route fa-fw\" style=\"color: red;\"></i></span>";
						html +=				"<span id=\"hideRoute_"+ i +"\" onclick=\"hideRoutePart("+i+")\" class=\"listIcon listIconHideRoute cursorPointer d-none\" title=\"<?php echo $locale_text["GPSMAP_hideRoute"]; ?>\" ><i class=\"fad fa-route fa-fw\"></i></span>";
						html +=				"&nbsp;&nbsp;"+printRouteChkBox+"&nbsp&nbsp;";
						html +=				"</div>";
						html +=			"</div>";
						html += 	"</div>";
					} else {
						html += 	"<div class=\"col-2 text-break text-wrap\">"+getFormattedMinutes(routeArray[i]["duration"]) + "<input  id=\"duration_" + i + "\" class=\"d-none\" value=\"" + routeArray[i]["duration"] +  "\" /></div>";
					}
					html += "</div>";
					
					var excelRow =  {};
					excelRow["start"]        	= routeArray[i]["startTime"];
					excelRow["startLocation"]   = "";
					excelRow["stop"]        	= routeArray[i]["endTime"];
					excelRow["stopLocation"]    = "";
					excelRow["distance"]    	= routeArray[i]["distance"].toFixed(2);
					excelRow["duration"]    	= getFormattedMinutes(routeArray[i]["duration"]);
					excelRow["durationRaw"]    	= routeArray[i]["duration"];
					excelData.push(excelRow);
					excelKeys[i] = excelData.length - 1; // Map id to index

                
                }
				
                
                var totalDurationTmp = getFormattedMinutes( (totalDuration / 1000) / 60);
                var totalDurationLabel = "";
                if(getFormattedMinutes( (totalDuration / 1000) / 60).hour > 0){
                    totalDurationLabel += getFormattedMinutes( (totalDuration / 1000) / 60).hour + " <?php echo $locale_text["GPSMAP_hour_short"]; ?> ";
                }
                if(getFormattedMinutes( (totalDuration / 1000) / 60).min > 0){
                    totalDurationLabel += getFormattedMinutes( (totalDuration / 1000) / 60).min + " <?php echo $locale_text["GPSMAP_min_short"]; ?>";
                }

                //totals
				html += "<div class=\"row bg-body-secondary fw-bold sticky-bottom\">";;
				html += 	"<div class=\"col-4 text-break text-wrap\"><?php echo $locale_text["GPSMAP_total"] . "  (" . $locale_text["GPSMAP_driving_time"] . ")";  ?></div>";
				html += 	"<div class=\"col-4 text-break text-wrap\"></div>";
				html += 	"<div id=\"totalDistanceSummation\" class=\"col-2 text-break text-wrap\">"+totalDistance.toFixed(2)+" <?php echo $locale_text["GPSMAP_distance"]; ?></div>";
				html += 	"<div id=\"totalDurationSummation\" class=\"col-2 text-break text-wrap;\">"+getFormattedMinutes(totalDuration)+"</div>";
				html += "</div>";
				
				$("#totalDistanceSummation_hidden").val(totalDistance.toFixed(2)+" <?php echo $locale_text["GPSMAP_distance"]; ?>");
                $("#totalDurationSummation_hidden").val(getFormattedMinutes(totalDuration));
				
				var excelTotal =  {};
				excelTotal["start"]        	= "<?php echo $locale_text["GPSMAP_total"] . "  (" . $locale_text["GPSMAP_driving_time"] . ")";  ?>";
				excelTotal["startLocation"] = "";
				excelTotal["stop"]        	= "";
				excelTotal["stopLocation"]  = "";
				excelTotal["distance"]    	= totalDistance.toFixed(2)+" <?php echo $locale_text["GPSMAP_distance"]; ?>";
				excelTotal["duration"]    	= getFormattedMinutes(totalDuration);
				excelTotal["durationRaw"]   = totalDuration;
				
				excelData.push(excelTotal);
				
				html += "</div>";  // div with max-height
				
				html += "</div>"; // div with border

            } else {
                html += "<div><?php echo $locale_text["GPSMAP_noData"]; ?></div>";
            }
			
			if (type == '*DAY*') {
				$("#day-gpsContainer").html(html);
			} else {
				$("#period-gpsContainer").html(html);
			}
			
			let geocodePromises = [];
			if(routeArray.length > 0){
				
                //  Reverse geo code to get address's, dones after HTML is set because of async reverse geo coding.
                for(i in routeArray){
					if (type == '*DAY*') {
						var startAddressId 	= 'routeStart_'+i;
						var endAddressId 	= 'routeEnd_'+i;
					} else {
						var startAddressId 	= 'routeStartPeriod_'+i;
						var endAddressId 	= 'routeEndPeriod_'+i;
					}
					const startLat 			= routeArray[i]["startLat"]
					const endLat 			= routeArray[i]["endLat"]
					const startLon 			= routeArray[i]["startLon"]
					const endLon 			= routeArray[i]["endLon"]
					geocodePromises.push(geoCodeLatLng(startLat, startLon, startAddressId));
					geocodePromises.push(geoCodeLatLng(endLat, endLon, endAddressId));
				}
				
			}

			// Wait for all geocoding promises to resolve before print or excel
			Promise.all(geocodePromises).then(() => {
				// Enable the column by removing the disabled class
				$("#printCol").removeClass("col-disabled"); // Enable the column
				$("#printExcelCol").removeClass("col-disabled"); // Enable the column
				$("#printPeriodCol").removeClass("col-disabled"); // Enable the column
				$("#getrouteBtnDay").removeClass("col-disabled"); // Enable button
				$("#getrouteBtnPeriod").removeClass("col-disabled"); // Enable button
			}).catch((error) => {
				console.error("Error with geocoding:", error);
			});
			
			
		},
		beforeSend: function() {
			$("#modal-message").removeClass("d-none").html( '<?php echo $locale_text["GPSMAP_rev_geo_in_progress"] ?>' );
		},
		complete: function() {
			$("#modal-message").addClass("d-none").html( '' );
		},
		error: function(xhr, status, error) {
			console.log(error);
		}
	});
	
}

//=============================================================================
// Get car locations.
//=============================================================================
function getCarlocations(mode){
	
	var parmData = 'time=' + lastUpdated
					+ '&mode=' + mode
				;
	
	$.ajaxq('getQueue',{
		url: 'gps_tracker_get_devices_latest.php',
		type: 'GET',
		data: parmData,
		dataType: 'json',
		success: function(jsonData) {
			//console.log(jsonData);
			
			if (jsonData["error"] != "") {
				console.log(jsonData["error"]);
			} else {
				lastUpdated = jsonData["time"];
			}	
			
			$.each( jsonData.data, function( index, item ){
				//console.log(item);
				var lat 		= item.lat;
				var lng 		= item.lng;
				var device_data = item.device_data;
				var imei 		= device_data.imei;
				var course 		= device_data.course;
				var online 		= item.online;
				var speed 		= item.speed;
				
				var status = 0;				// red, offline (no data in 24h)
				var statusColor = 'bg-danger';
				var titleText = offlineLegend;
				if (online != "offline") {
					if (speed <= 5) {
						status = 1;			// yellow, paused
						statusColor = 'bg-warning';
						titleText = yellowLegend;
					} else {
						status = 2;				//green, driving
						statusColor = 'bg-success';
						titleText = onlineLegend;
					}	
				}
				
				var n = 1;
				
				if (imeiList.includes(imei)) {
					
					mapGlobals.JSON_locationList[imei] = item;
					
					carData[imei] = [];
					
					var latLng = new google.maps.LatLng(lat, lng);
					var markerData = new MarkerData("employee", latLng, "", "em_" + imei, imei, status, lat, lng, course);
					n++;
					
					carData[imei]["marker"] = markerData;
					
					if ($('#employeeShowOffline').prop('checked') || status != 0) {
						addMarker(markerData);
						$("#emp_" + imei).addClass("listItemOn");
					}
					
					// Changes employee status 
					updateStatusColor(imei, statusColor, titleText); 
					
				}
				
			});
			
			
		},
		error: function(xhr, status, error) {
			console.log(error);
		}
	});
	
}

//=============================================================================
// update employee status Color
//=============================================================================
function updateStatusColor(imei, newClass, titleText) {
	const empId = "emp_"+imei;
	const badge = document.querySelector(`#${empId} .badge`);
  
	if (badge) {
		// Remove existing background color classes
		badge.classList.remove('bg-danger', 'bg-success', 'bg-warning');
    
		// Add the new background color class
		badge.classList.add(newClass);
		
		// Set the title attribute
		if (titleText) {
		  badge.setAttribute('title', titleText);
		}
	}
	
	if (newClass == "bg-danger") {
		$("#"+empId).addClass("isOffline");
		if ($('#employeeShowOffline').prop('checked')) $("#"+empId).removeClass("d-none");
		else $("#"+empId).addClass("d-none");
	} else {
		$("#"+empId).removeClass("isOffline");
		$("#"+empId).removeClass("d-none");
	}
}

//=============================================================================
// add Marker to the map
//=============================================================================
function addMarker(markerData){
	
	if(!markerData){
		return false;
	}
	
    let marker = mapGlobals.allMarkers[markerData.id]; // Get the marker by ID
    
	//	General marker settings
	if (marker) {
        // Update existing marker
		//console.log("update")
        marker.setPosition(markerData.latLng);
        marker.address = markerData.address; // Custom property
        marker.taskStatus = markerData.taskStatus; // Custom property
        marker.taskColor = markerData.taskColor; // Custom property
    } else {
        // Create a new marker
		//console.log("new")
        marker = new google.maps.Marker({
            id: markerData.id,
            position: markerData.latLng,
            map: mapGlobals.map,
            address: markerData.address,
            draggable: false,
            taskStatus: markerData.taskStatus || "",
            taskColor: markerData.taskColor || ""
        });

        // Add the new marker to the global array
        mapGlobals.allMarkers[markerData.id] = marker;
    }
	
	//	Specific marker settings
	switch(markerData.type){
		case "customer":
			marker.html = fillInfoWindow(markerData);
			mapGlobals.currentCustomerMarker = marker;
			setMapCenter(markerData.latLng);
			marker.setIcon("images/marker/marker_customer1.png");
			marker.setTitle("<?php echo $locale_text["GPSMAP_customer"]; ?>");
			break;
		case "address":
			mapGlobals.addressMarker = marker;
			setMapCenter(markerData.latLng);
			marker.setIcon("images/marker/marker_address.png");
			break;
		case "employee":
			var persID = markerData.id.split("_");
			var empId = persID[1];
			var init = "";
			try {
				var init = mapGlobals.JSON_employeeList[empId].initials;
			}
			catch(err) {
				return;
			}
			var empName = mapGlobals.JSON_employeeList[empId].name;
			var mobilePhoneNumber = mapGlobals.JSON_employeeList[empId].mobilePhone;
			var course = markerData.course;
			var bearing = getDirection(course);
			marker.setIcon("include/marker_generator.php?text=" + init + "&type=" + markerData.online + "&bearing=" + bearing);
            
            checkID = "em_" + persID[1];
            for (var i = 0; i < mapGlobals.markerCluster.markers_.length; i++) {
                if (checkID == mapGlobals.markerCluster.markers_[i].id){
                   mapGlobals.markerCluster.removeMarker(mapGlobals.markerCluster.markers_[i]); 
                }
            }

			mapGlobals.gpsEmployeeMarkersArray.push(marker);          
            mapGlobals.markerCluster.addMarker(marker);

			
			break;
		case "location":
			marker.setIcon("images/marker/localmarker.png");
			mapGlobals.gpsEmpLocationMarkers[markerData.id] = marker;
			break;
		case "home":
			marker.html = fillInfoWindow(markerData);
			mapGlobals.homeMarker = marker;
			marker.setIcon("images/marker/marker_home.png");
			marker.setTitle("<?php echo $locale_text["GPSMAP_legendHome"]; ?>");
            setMapCenter(markerData.latLng); // added to get map showing
			break;
		case "department":
			marker.html = fillInfoWindow(markerData);
			marker.setIcon("images/marker/marker_department.png");
			marker.setTitle(markerData.description);
			break;
		case "machine":
            marker.html = fillInfoWindow(markerData);
			marker.setIcon("images/marker/marker_machines.png");
            marker.setTitle(markerData.description);
			setMapCenter(markerData.latLng);
			mapGlobals.selectedMachines[markerData.id] = marker;
			break;
		case "job":
			switch(markerData.taskStatus){
						case  0:   // NotAssigned 
                            color = "<?php echo $DFT_COLOR_JOB_NOT_ASSIGNED; ?>";
							colorCode = color.substring(1);
							taskIcon = "images/marker/marker_job_"+colorCode+".png";
                            break;
						case  1:   // Active
                            color = "<?php echo $DFT_COLOR_JOB_ACTIVE; ?>";
							colorCode = color.substring(1);
							taskIcon = "images/marker/marker_job_"+colorCode+".png";
                            break;
                        case  2:   // InProgress
                            color = "<?php echo $DFT_COLOR_JOB_START; ?>";
							colorCode = color.substring(1);
							taskIcon = "images/marker/marker_job_"+colorCode+".png";
                            break;
                        case  3:   // OnHold 
                            color = "<?php echo $DFT_COLOR_JOB_ONHOLD; ?>";
							colorCode = color.substring(1);
							taskIcon = "images/marker/marker_job_"+colorCode+".png";
                            break;
                        case  4:   // Review
                            color = "<?php echo $DFT_COLOR_JOB_REVIEW; ?>";
							colorCode = color.substring(1);
							taskIcon = "images/marker/marker_job_"+colorCode+".png";
                            break;
                        case  5:   // Completed
                            color = "<?php echo $DFT_COLOR_JOB_CLOSED; ?>";
							colorCode = color.substring(1);
							taskIcon = "images/marker/marker_job_"+colorCode+".png";
                            break;
                        case  6:   // DFT_COLOR_JOB_INVOICED 
                            color = "<?php echo $DFT_COLOR_JOB_PARTLY_DONE; ?>";
							colorCode = color.substring(1);
							taskIcon = "images/marker/marker_job_"+colorCode+".png";
                            break;
                        case  7:   // Cancelled
                            color = "<?php echo $DFT_COLOR_JOB_CANCEL; ?>";
							colorCode = color.substring(1);
							taskIcon = "images/marker/marker_job_"+colorCode+".png";
                            break;
                        default:
                            color = "<?php echo $DFT_COLOR_JOB_DEFAULT; ?>";
							colorCode = color.substring(1);
							taskIcon = "images/marker/marker_job_"+colorCode+".png";
                            break;
			}
			mapGlobals.selectedJobs[markerData.id] = marker;
			//marker.setIcon("images/marker/marker_job.png");
            marker.setTitle(markerData.description);
			marker.setIcon(taskIcon);
			marker.setZIndex(100000);
            marker.taskStatus = markerData.taskStatus;
            marker.taskColor = colorCode;
            marker.taskPlannedperson = markerData.taskPlannedperson;
			//setMapCenter(markerData.latLng); 
            mapGlobals.markerCluster.addMarker(marker);
			break;
		case "jobCustomer":
			marker.setIcon("images/marker/marker_cust.png");
			setMapCenter(markerData.latLng);
			mapGlobals.jobInfoCustMarker = marker;
			break;
		case "jobDelivery":
			marker.setIcon("images/marker/marker_del.png");
			setMapCenter(markerData.latLng);
			mapGlobals.jobInfoDelMarker = marker;
			break;
	}
    
	marker.addListener('click', function(m) {
	var markertype = markerData.id.split("_"); 
	if(markertype[0] == "task") {
		//getJobEdit(markertype[1], m);
        if(mapGlobals.userLevel != 1) {
          //  Planner / admins can change all jobs
          javascript:PopWin("../../details.php?taskid="+markertype[1]+"&personid=&referencecode=&status=0",720,1000, m);
        } else {
          //  Regular user may only change own job.
          if(mapGlobals.loggedInUser == markerData.taskPlannedperson || mapGlobals.loggedInUser == 0) {
            javascript:PopWin("../../details.php?taskid="+markertype[1]+"&personid=&referencecode=&status=0",720,1000, m);
          } else {
            $javascript:alert('<?php echo $locale_text["ERROR_EDIT_NOT_ALLOWED"]?>');
          }
        }
	}
  });
  
	marker.addListener('mouseover', function(m) {
	var markertype = markerData.id.split("_"); 
	var container = $(document.getElementById("mapContainer"));
	if (!container.find('#tooltip').length)
		container.append(jobtooltip);
	if(markertype[0] == "task") {
			projection = overlay.getProjection();
			var pixel = projection.fromLatLngToContainerPixel(marker.getPosition());
			toolTipTimer = setTimeout(function() { showJobInfoPopup(markertype[1], pixel.x, pixel.y); }, 400);
	}
  });
  
	marker.addListener('mouseout', function(m) {
	var markertype = markerData.id.split("_"); 
	if(markertype[0] == "task") {
		clearTimeout(toolTipTimer);
		 hideJobInfoPopup();
	}
  });

	
    //  Job marker have no info window so far.
	if(markerData.type != "job"){
    	/*	Closing infowindow on the cross, apparently google maps v3 has a bug and the event is fired twice.
    	*	No problem here, but if a more complex function is called later on considere it and take measures.
    	*/
    	google.maps.event.addListener(mapGlobals.infoWin, "closeclick", function(){  
        	if(mapGlobals.empInfoWinShown){
        		mapGlobals.empInfoWinShown = false;
        	}
    	});
    	
    	google.maps.event.addListener(marker, "click", function () {	//	Register click event on marker and set info window content
    		if(markerData.type == "address"){
				
    			geoCodeCooridinates(this);			
    		}
    		else if(markerData.type == "employee"){
                mapGlobals.selectedEmployee = persID[1];
                setMapCenter(markerData.latLng);

                $("#gpsSummationHeader, #gpsSummationContainer").addClass("hidden");
                var empObj = {
                    empId : mapGlobals.selectedEmployee,
                    empName : empName,
                    mobilePhoneNumber : mobilePhoneNumber
                }
				//console.log("emp id " + mapGlobals.selectedEmployee);
                //showEmpInfo(empObj);
                $("#empInfo_"+mapGlobals.selectedEmployee).click();
    		}
    		else{
    			mapGlobals.infoWin.setContent(this.html);
    			mapGlobals.infoWin.open(mapGlobals.map, this);
    			if(markerData.type == "employee"){
    				mapGlobals.empInfoWinShown = true;
    				mapGlobals.empInfoWinID = markerData.id;
    				var empID = markerData.id.split("_");
    				mapGlobals.selectedEmployee = empID[1];
    			}
    			else{
    				mapGlobals.empInfoWinShown = false;
    			}
    		}
    	});
	}
   	
}

//=============================================================================
// Remove a specific marker
//=============================================================================
function removeMarker(marker){
	
	if(marker != null){
		const markerId = marker.id;
		marker.setMap(null);
		// Update the allMarkers array by removing the marker
        delete mapGlobals.allMarkers[markerId];
	}
}

//=============================================================================
//Remove an employee marker
//=============================================================================
function removeEmployeeMarker(personID){
	for(i in mapGlobals.gpsEmployeeMarkersArray){
		if(mapGlobals.gpsEmployeeMarkersArray[i].id == "em_" + personID){
			removeMarker(mapGlobals.gpsEmployeeMarkersArray[i]);
            mapGlobals.markerCluster.removeMarker(mapGlobals.gpsEmployeeMarkersArray[i]);
		}        
	}
}

//=============================================================================
// Get address from coordinates
//=============================================================================
function geoCodeCooridinates(marker){
	var address = "";
	if (marker.address != "") {
		address = marker.address;
		mapGlobals.infoWin.setContent("<div class='infoBoxWin boldText'>" + address + "</div>");
		mapGlobals.infoWin.open(mapGlobals.map, marker);
	} else {
		var geocoder = new google.maps.Geocoder();
		geocoder.geocode({'latLng': marker.position}, function(results, status) {
			if(status == google.maps.GeocoderStatus.OK){
				if(results[0]){
					address = results[0].formatted_address;
					mapGlobals.infoWin.setContent("<div class='infoBoxWin boldText'>" + address + "</div>");
					mapGlobals.infoWin.open(mapGlobals.map, marker);

				}
			}
			else{
				//alert("Adress retrieval failed due to: " + status);
			}
			

			//  Remove marker when close on infowin is clicked
			google.maps.event.addListener(mapGlobals.infoWin,'closeclick',function(){
				marker.setMap(null);
			});
			
		});
	}
}

//=============================================================================
// Update Job with coordinates
//=============================================================================
function updateCoordinates(thisJobUuid, longitude, latitude){
	
		var parmData = 'lat=' + latitude
						+ '&lng=' + longitude
						+ '&uuid=' + thisJobUuid
					;
					
	$.ajax({
		url: 'ajax_update_job.php',
		type: 'GET',
		data: parmData,
		dataType: 'json',
		success: function(jsonData) {
			
			//console.log(jsonData);
	
		},
		error: function(xhr, status, error) {
			console.log(error);
			
		}
	});
	
}


//=============================================================================
// Get address from coordinates 
//=============================================================================
function geoCodeLatLng(lat, lng, addressId){
	// use promise to keep track on when geocoding are done
	return new Promise((resolve, reject) => {
	
		var parmData = 'lat=' + lat
						+ '&lng=' + lng
					;
		
		$.ajaxq('getQueue',{
			url: 'gps_tracker_address_reverse.php',
			type: 'GET',
			data: parmData,
			dataType: 'json',
			success: function(jsonData) {
				
				if (jsonData["error"] != "") {
					console.log(jsonData["error"]);
					const errmsg = '<?php echo $locale_text["GPSMAP_unknown_location"] ?>';
					$("#"+addressId).removeClass("spinner-border").removeClass("spinner-border-sm");
					$("#"+addressId).html(errmsg);
				} else {
					const location = jsonData["data"]["location"];
					const houseNo = (location["house"] != null ? location["house"] : "")
					var addText = (location["road"] != null ? location["road"] + " " + houseNo + ", <br> " : "");
					addText += ((location["city"] != null || location["zip"] != null) ? location["zip"] + " " + location["city"] : " ");
					if (addText == "") addText = '<?php echo $locale_text["GPSMAP_unknown_location"] ?>';
					$("#"+addressId).removeClass("spinner-border").removeClass("spinner-border-sm");
					$("#"+addressId).html(addText);
					
					//update excel
					var addTextExcel = result = addText.replace("<br>", "");
					var idArr = addressId.split("_");
					if (idArr[0] == "routeStart" || idArr[0] == "routeStartPeriod") {
						if (excelKeys[idArr[1]] !== undefined) {
							excelData[excelKeys[idArr[1]]].startLocation = addTextExcel;
						}
					} else 	if (idArr[0] == "routeEnd" || idArr[0] == "routeEndPeriod") {
						if (excelKeys[idArr[1]] !== undefined) {
							excelData[excelKeys[idArr[1]]].stopLocation = addTextExcel;
						}
					} 
					
				}
				resolve(); // Resolve the promise once the AJAX call is complete
		
			},
			error: function(xhr, status, error) {
				console.log(error);
				reject(error); // Reject the promise if there's an error
			}
		});
	
	 });
}

//=============================================================================
// Get coordinates for address
//=============================================================================
function geoCodeAddress(markerData, showResultList){
    if(showResultList == undefined){
        showResultList = false;
    }
	
    if ((markerData.latitude != undefined && markerData.longitude != undefined) && (markerData.latitude != "" && markerData.longitude != "") ){
        var lat = markerData.latitude;
        var lng = markerData.longitude;
        var latlng = new google.maps.LatLng(lat, lng);
        markerData.latLng = latlng;
        addMarker(markerData);
        return latlng;
    } else {
        var geocoder = new google.maps.Geocoder();
        geocoder.geocode({'address' : markerData.address}, function(results, status){
            if (status == google.maps.GeocoderStatus.OK){
				
				if (markerData.type == "job") {
					const latitude = results[0].geometry.location.lat();
					const longitude = results[0].geometry.location.lng();
					var jobIdArr = markerData.id.split("_");
										
					const jobId = jobIdArr[1]
					const thisJob = mapGlobals.JSON_jobList[jobId];
					const thisJobUuid = thisJob.id;
				   
					mapGlobals.JSON_jobList[jobId]["latitude"] = latitude;
					mapGlobals.JSON_jobList[jobId]["longitude"] = longitude;
				   
					updateCoordinates(thisJobUuid, longitude, latitude);
			    }
				
                if(showResultList){
                    var addressSearchResult = $("#addressSearchResult");
                    addressSearchResult.hide();
                    addressSearchResult.empty();
                    if(results.length > 1){  //  More than 1 result.
						const $button = $("#addressSearchBtn");
						// Dispose of the existing popover to reset its content
						$button.popover("dispose");
                        var resultLi = "<ul class='searchResultList list-group' style='cursor: pointer;'>";
                        for(i in results){
                            resultLi +=    "<li class='custResultLink list-group-item' id='"+ results[i].geometry.location.lat() + "_" + results[i].geometry.location.lng() +"'>" + results[i].formatted_address + "</li>";
                        }
                        resultLi +=    "</ul>";
						
						$button.popover({
							trigger: "manual",
							placement: "right",
							html: true,
							content: resultLi
						});
						
						// Attach the event listener for 'inserted.bs.popover' before showing the popover
						$button.on('inserted.bs.popover', function () {
							// Bind click event to each .custResultLine element within the popover
							$('.popover-body .custResultLink').off('click').on('click', function () {
								var thisId = this.id;
								var idArr = thisId.split("_");
								
								var latlng = new google.maps.LatLng(idArr[0], idArr[1]);
								var address = $(this).text();
								var markerData = new MarkerData("address", latlng, address, "addressMarker", null, null, null);
								addMarker(markerData);
								$("#addressSearchBtn").popover("hide");
								
							});
						});
						
						$button.popover("show");
						
                    }
                    else{   //  Only 1 result.
                        var lat = results[0].geometry.location.lat();
                        var lng = results[0].geometry.location.lng();
                        var latlng = new google.maps.LatLng(lat, lng);
                        markerData.latLng = latlng;
						markerData.address = results[0].formatted_address;
                        addMarker(markerData);
                    }
                }
                else{
                    var lat = results[0].geometry.location.lat();
                    var lng = results[0].geometry.location.lng();
                    var latlng = new google.maps.LatLng(lat, lng);
                    markerData.latLng = latlng;
					markerData.address = results[0].formatted_address;
                    addMarker(markerData);
                    return latlng;

               } 
            }
            else{
                //alert("Geocode was not successful for the following reason: " + status);
                alert(markerData.address + "\n<?php echo $locale_text["GPSMAP_noAddress"]; ?>");
                if(markerData.type == "job"){
                    $("#" + markerData.id).removeClass("listItemOn");
                }
                return false;

            }
        });

    }
}

//=============================================================================
// Calculate the time difference between two stamps.
//=============================================================================
function timeDifference(stamp1, stamp2){
    return Math.abs(stamp1-stamp2);
}

//=============================================================================
// Format sec as hours and min
//=============================================================================
function getFormattedMinutes(totalSeconds){
	var hours = Math.floor(totalSeconds / 3600);
	totalSeconds = totalSeconds % 3600;
	var minutes = Math.floor(totalSeconds / 60);
	var seconds = totalSeconds % 60;
	var formattedTime = (hours > 0 ? hours + " <?php echo $locale_text["GPSMAP_hour_short"]; ?> " : "");
	formattedTime += (minutes > 0 ? minutes + " <?php echo $locale_text["GPSMAP_min_short"]; ?> " : "");
	if (formattedTime == "") formattedTime = "<1 <?php echo $locale_text["GPSMAP_min_short"]; ?>"; 
	return formattedTime;
}


//=============================================================================
// Show employees path on map. Draw a polyline. Print marker according to interval
//=============================================================================
function showRoute(){
	var lastCoord = new google.maps.LatLng();
	var gpsEmpPathPolyline = new Array();
	for(i in mapGlobals.JSON_gpsTransactions){
		var tempLatLng = new google.maps.LatLng(mapGlobals.JSON_gpsTransactions[i].latitude, mapGlobals.JSON_gpsTransactions[i].longitude);

		//	For polyline
		if(tempLatLng.lat() != 0 && tempLatLng.lng() != 0){	//	0,0 coords not show on line
			if(tempLatLng.lat() != lastCoord.lat() && tempLatLng.lng() != lastCoord.lng()){
				gpsEmpPathPolyline.push(tempLatLng);
			}
		}
		lastCoord = tempLatLng;
		
	}
	mapGlobals.routePolyline = drawPolyline(gpsEmpPathPolyline);
	setMapCenter(tempLatLng);
	mapGlobals.map.setZoom(11);
}

//=============================================================================
//  Show a specific route
//=============================================================================
function showRoutePart(id){
    $("#hideRouteBtn").trigger("click");
    removePolyline(mapGlobals.routePolyline);

    var startStamp = mapGlobals.routeArray[id]["startTimeStamp"];
    var stopStamp  = mapGlobals.routeArray[id]["endTimeStamp"];

    var latLngList = new Array();
    var routeStarted = false;
    for(i in mapGlobals.JSON_gpsTransactions){
        //  Transactions without coordinate is skipped
        if(!mapGlobals.JSON_gpsTransactions[i].latitude || !mapGlobals.JSON_gpsTransactions[i].longitude){
            continue;
        }
        
        if(mapGlobals.JSON_gpsTransactions[i].timestamp == startStamp){
            routeStarted = true;
        }
        if(routeStarted){
            var latLng = new google.maps.LatLng(mapGlobals.JSON_gpsTransactions[i].latitude, mapGlobals.JSON_gpsTransactions[i].longitude);
            latLngList.push(latLng);
        }
        if(mapGlobals.JSON_gpsTransactions[i].timestamp == stopStamp){
            routeStarted = false;
            break;
        }
    }
    
    mapGlobals.routePolyline = drawPolyline(latLngList);
    setMapCenter(latLng);   
	mapGlobals.map.setZoom(11);	
    
    $("#showRoute_"+ id).addClass("d-none");
    $("#hideRoute_"+ id).removeClass("d-none");

}

//=============================================================================
//  Hide a specific route
//=============================================================================
function hideRoutePart(id){
    removePolyline(mapGlobals.routePolyline);
    $("#showRoute_"+ id).removeClass("d-none");
    $("#hideRoute_"+ id).addClass("d-none");
}

//=============================================================================
// Draw a polyline between cordinates
//=============================================================================
function drawPolyline(latLngList){
	var polyline = new google.maps.Polyline({
		path: latLngList,
		strokeColor: "#FF3D64",
		strokeOpacity: 1.0,
		strokeWeight: 3
	});
	polyline.setMap(mapGlobals.map);
	google.maps.event.addListener(polyline, 'click', function(event) {
		removeMarker(mapGlobals.clickedPolyLineMarker);
		var latLng = new google.maps.LatLng(event.latLng.lat(), event.latLng.lng());
		mapGlobals.clickedPolyLineMarker = new google.maps.Marker({
	    	id: "clickedPolyline",
	    	position: latLng,
	    	icon: "",
	    	map: mapGlobals.map,
	    	draggable: false
		});
		geoCodeCooridinates(mapGlobals.clickedPolyLineMarker)
	});
	return polyline;
}

//=============================================================================
// Removes polyline from map
//=============================================================================
function removePolyline(polyline){
	if(polyline != undefined){
		polyline.setMap(null);
	}
}


//=============================================================================
// Recalculate Summations
//=============================================================================
function recalculateSummations(){
    var totalDistance = 0;
    var totalDuration = 0;
    var hasChecked = false;
	var elementsArray = document.getElementsByClassName("inSummation");
	
    for(var i=0; i<elementsArray.length; i++) {
        var id = elementsArray[i].id; 
        var idArr = id.split("_");
        var checked  = elementsArray[i].checked;
        if (checked) {
            hasChecked = true;
            var thisDistance = document.getElementById("distance_"+idArr[1]).value;
            var thisDuration = document.getElementById("duration_"+idArr[1]).value;
            totalDistance += parseFloat(thisDistance.replace(',', '.'));
            totalDuration += parseInt(thisDuration);
        } else {
			$("#printGPSTransactionsAllCheck").prop('checked', false); // Unchecks it
		}
    }
    if (hasChecked) {
        $("#totalDistanceSummation").html(totalDistance.toFixed(1) + " km");
        $("#totalDurationSummation").html(getFormattedMinutes(totalDuration));
    } else {
        $("#totalDistanceSummation").html($("#totalDistanceSummation_hidden").val());
        $("#totalDurationSummation").html($("#totalDurationSummation_hidden").val());
    }
}

//=============================================================================
//Remove all markers from a given list
//=============================================================================
function removeAllMarkers(markerList){
	for(i in markerList){
		markerList[i].setMap(null);
	}
}

//=============================================================================
//  Center map on a latlng
//=============================================================================
function setMapCenter(latlng){
	mapGlobals.map.setCenter(latlng);	// Instantly to location
}

//=============================================================================
//  Search address
//=============================================================================
function addressSearch(){
	var address = $("#addressSearchVal").val();
	if(address != ""){
		removeMarker(mapGlobals.addressMarker);
		var markerData = new MarkerData("address", null, address, "addressMarker", null, null, null);
		geoCodeAddress(markerData, true);
	}
	else{
	    $("#addressSearchResult").hide();
	}
}

//=============================================================================
//  Search clear
//=============================================================================
function addressClear(){
	$("#addressSearchVal").val("");
	removeMarker(mapGlobals.addressMarker);
	$("#addressSearchResult").hide();
}


//=============================================================================
// toggle sidebar
//=============================================================================
function toggleSidebar() {
    const sidebar = document.getElementById("sidebar");
    const toggleBtn = document.getElementById("toggle-btn");

    sidebar.classList.toggle("show");

    // Update button text based on sidebar visibility
    if (sidebar.classList.contains("show")) {
		$('#toggle-btn').html('<?php echo $locale_text["GPSMAP_menu_hide"]; ?>');
    } else {
       $('#toggle-btn').html('<?php echo $locale_text["GPSMAP_menu_show"]; ?>');
    }
}

//=============================================================================
// get directions from degrees
//=============================================================================
function getDirection(degrees) {
	const directions = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'];
	const anglePerDirection = 45;
	const offsetAngle = 22.5;
	
	// Normalize degrees to be within 0-360
    const adjustedDegrees = (degrees % 360 + 360) % 360;
	
	// Determine which of the 8 segments it falls into
    const index = Math.floor((adjustedDegrees + offsetAngle) / anglePerDirection) % directions.length;
	const direction = directions[index];

    return direction;
}

//=============================================================================
// Search for customers
//=============================================================================
function customerSearch() {
	var createJobWindow = $("#createJobWindow");
	if(createJobWindow.is(":visible")){
		createJobWindow.addClass("hidden");
		resetCreateJobWindow();
	}
	mapGlobals.custSearching = true;
	var searchString = $("#customerSearchVal").val();
	
	mapGlobals.searchString = searchString;
	if(searchString == "<?php echo $locale_text["GPSMAP_writesearch"];?>"){
		$("#customerSearchVal").val("");
		searchString = "";
	}
	
	// Prevent duplicate requests
	if (searchString === lastSearchString) {
		return;
	}
	  
	lastSearchString = searchString;
	getCustomerList(searchString);
}

//=============================================================================
// Get a customer list. If only one customer, info is filled otherwise a list is show with possible customers 
//=============================================================================
function getCustomerListTimer(bypassTimer) {
	clearTimeout(inputTimer);
	
	var searchString = $("#customerSearchVal").val();
	if (searchString.length < 3) {
		return;
	} else if (searchString.length === 3) {
		customerSearch();
		return;
	}
	
	if (!bypassTimer) {
		inputTimer = setTimeout(function () {getCustomerListTimer(true);}, 500);
		return;
	}

	customerSearch();
}

//=============================================================================
// Get a customer list
//=============================================================================
function getCustomerList(searchString){
	
	// Limit queue to one pending request
	if (custQueueCount > 0) {
		$.ajaxq.clear("custSearchQueue");
		custQueueCount = Math.max(custQueueCount - 1, 0); // Decrement the queue count safely
	}
	
	custQueueCount++;
	
	parmData = 'searchString='+encodeURI(searchString)
				;
				
	 $.ajaxq("custSearchQueue", {
		cache: false,
		url: "ajax_get_customer_search.php",
		dataType: "json",
		data: parmData,
		success: function(jsonData){
			//console.log("Search request completed for:", searchString);
			//console.log(jsonData);
			if (jsonData["error"] != "") {
				console.log(jsonData["error"]);
			} else {
				delete jsonData["error"];			
				
				mapGlobals.JSON_customerList = jsonData;
				
				if (custPopoverVisible) {
					$(".popover-body").empty(); // Clear previous popover content
				} else {
					// Ensure no old data lingers in the popover if it's not visible
					$("#customerSearchBtn").popover("dispose"); // Completely remove the popover instance
				}
				
				var resultHTML = "<div id='customerSearchResult' class='resultList'></div>";
				var liCount = 0;
				resultHTML += "<ul id='customerSearchResultUL' class='searchResultList list-group'>"; 
				$.each( jsonData, function( index, item ){
					
					if (item.length !== 0) {
						liCount++;
					
						const ID		 	= item.id;
						const referenceID 	= item.code;
						
						mapGlobals.JSON_customerListID[referenceID] = ID;
						
						const name 			= item.name;
						const location 		= ((!item.location || item.location.toUpperCase() == 'NULL') ? "" : item.location);
						const street		= ((!item.street || item.street.toUpperCase() == 'NULL') ? "" : item.street);
						const zipCode	 	= ((!item.zipCode || item.zipCode.toUpperCase() == 'NULL') ? "" : item.zipCode);
						const city	 		= ((!item.city || item.city.toUpperCase() == 'NULL') ? "" : item.city);
						const country	 	= ((!item.country || item.country.toUpperCase() == 'NULL') ? "" : item.country);
						
						var display			= "("+referenceID+") "+name;
							  
						const displayHit 	= display.toUpperCase().includes(searchString.toUpperCase());
						const locationHit 	= location.toUpperCase().includes(searchString.toUpperCase());
						const streetHit 	= street.toUpperCase().includes(searchString.toUpperCase());
						const zipCodeHit 	= zipCode.toUpperCase().includes(searchString.toUpperCase());
						const cityHit 		= city.toUpperCase().includes(searchString.toUpperCase());
						const countryHit 	= country.toUpperCase().includes(searchString.toUpperCase());
							  
						resultHTML += "<li id='refID_" + referenceID + "' class='custResultLink cursorPointer list-group-item'>" + (displayHit ? "<b>" : "") + display + (displayHit ? "</b>" : "") + ", "  + (locationHit ? "<b>" : "") + (location != "" ? location + ", " : "") + (locationHit ? "</b>" : "") + (streetHit ? "<b>" : "") + (street != "" ? street + ", " : "") + (streetHit ? "</b>" : "") + (zipCodeHit ? "<b>" : "") + zipCode + (zipCodeHit ? "</b>" : "") + " "+ (cityHit ? "<b>" : "") +  city + (cityHit ? "</b>" : "") + " "+ (countryHit ? "<b>" : "") +  country + (countryHit ? "</b>" : "") + "</li>";
					}
				});
				resultHTML += "</ul>";
				
				if (liCount == 0){	// No result
					  
					resultHTML += "<?php echo $locale_text["GPSMAP_noData"]; ?>";
					mapGlobals.custSearching = false;
				}
				resultHTML += "</div>";
				
				// Update content directly in the popover if it is already visible
				if (custPopoverVisible) {
					$(".popover-body").empty().html(resultHTML);
					
					// Re-bind click events to the updated content
					$('.popover-body .custResultLink').off('click').on('click', function () {
						var thisId = this.id;
						var idArr = thisId.split("_");

						if (mapGlobals.currentCustomerMarker !== undefined) {
							removeMarker(mapGlobals.currentCustomerMarker);
						}
						for (var i in mapGlobals.selectedMachines) {
							removeMarker(mapGlobals.selectedMachines[i]);
							if (i in mapGlobals.selectedMachines) { // If key exists, it might not because of async reverse geo code
								delete mapGlobals.selectedMachines[i];
							}
						}

						fillInCustomerInfo(idArr[1]);

						$("#hideCustomerBtn").removeClass('d-none');
						$('#createCustomerJobBtn').prop('disabled', false);

						$("#refFilterResult").hide();
						$("#refFilter").val("");
					});
				} else {
					// Initialize the popover if not visible
					$("#customerSearchBtn").popover({
						title: "<?php echo $locale_text['GPSMAP_Machine']; ?>",
						trigger: "manual",
						placement: "bottom",
						html: true,
						customClass: "wide-popover",
						content: resultHTML
					});
					
					$("#customerSearchBtn").popover("show");
					custPopoverVisible = true;
					
					// Bind click events to the newly created content
					$('.popover-body .custResultLink').off('click').on('click', function () {
						
						var thisId = this.id;
						var idArr = thisId.split("_");
						
						if (mapGlobals.currentCustomerMarker !== undefined) {
							removeMarker(mapGlobals.currentCustomerMarker);
						}
						for (var i in mapGlobals.selectedMachines) {
							removeMarker(mapGlobals.selectedMachines[i]);
							if (i in mapGlobals.selectedMachines) { // If key exists, it might not because of async reverse geo code
								delete mapGlobals.selectedMachines[i];
							}
						}

						fillInCustomerInfo(idArr[1]);

						$("#hideCustomerBtn").removeClass('d-none');
						$('#createCustomerJobBtn').prop('disabled', false);

						$("#refFilterResult").hide();
						$("#refFilter").val("");
					});
				}
				
			}
			
		},
		complete: function () {
		  custQueueCount = Math.max(custQueueCount - 1, 0); // Decrement the queue count safely
		},
		error: function (xhr, status, error) {
		  if (status !== "abort") {
			console.error("AJAX error:", status, error);
		  }
		}
	});

}

//=============================================================================
// Fill customer infobox for specific customer
//=============================================================================
function fillInCustomerInfo(refID){
	
	$.each( mapGlobals.JSON_customerList, function( index, item ){
		if(item.referenceID == refID){
			
			const location 		= ((!item.location || item.location.toUpperCase() == 'NULL') ? "" : item.location);
			const street		= ((!item.street || item.street.toUpperCase() == 'NULL') ? "" : item.street);
			const zipCode	 	= ((!item.zipCode || item.zipCode.toUpperCase() == 'NULL') ? "" : item.zipCode);
			const city	 		= ((!item.city || item.city.toUpperCase() == 'NULL') ? "" : item.city);
			const country	 	= ((!item.country || item.country.toUpperCase() == 'NULL') ? "" : item.country);
			
			$("#customerSearchResult").hide();
			$("#customerSearchResultUL").html("");
			$("#customerSearchVal").val("");
			$("#jobCreateModal-custId").val(item.id);
			$("#jobCreateModal-serviceunitId").val("");
			mapGlobals.selectedCustomer = item;
			$("#createJobFromCustomerBtn").removeClass("mapBtnDisabled");
			$("#custNumber").html("<span>"+item.code+"</span>" + "<span id='customerInfoIcon' class='listIconInfo'><i class='fa-solid fa-circle-info'></i></span>");
			$("#custName").html(item.name);
			$("#custLocation").html(location);
			$("#custAddress").html(street);
			$("#custZipCity").html(zipCode + " " +  city);
			if(item.streetName != ""){
					var address = street + " " + zipCode + " " + city + " " + country;
					var markerData = new MarkerData("customer", null, address, "ref_" + item.referenceID, item.name);
					geoCodeAddress(markerData);
			}
			return false; //breake out
		}
	});
	
	// Show the popover
    $("#customerSearchBtn").popover("hide");
	custPopoverVisible = false;  // Set the popover state to hidden
	$.ajaxq.abort("custSearchQueue"); //aborts the current search request
	
	
	// Attach hover handler to .listIconInfo within the search results 
    $("#customerContentWrapper").on("mouseenter", ".listIconInfo", function () {
        const $icon = $(this);

        // Dispose of any existing popover to prevent duplicates and clear any previous timeout
        $icon.popover("dispose");
		
		//notice no extra data (øvrige data) in 2.0
		var resultHTML = '<div class="row">';                   
		resultHTML += '<div class="col-3 fw-bold"><?php echo $locale_text["GPSMAP_number"]; ?></div>';
		resultHTML += '<div class="col-3 border-end">' +  mapGlobals.selectedCustomer.referenceID + '</div>'; 
		resultHTML += '<div class="col-3 fw-bold"><?php echo $locale_text["GPSMAP_contact_person"]; ?></div>';
		resultHTML += '<div class="col-3">' +  (mapGlobals.selectedCustomer.contactName !== null && mapGlobals.selectedCustomer.contactName.toUpperCase() != 'NULL' ? mapGlobals.selectedCustomer.contactName : "") + '</div>'; 
		resultHTML += "</div>";

		resultHTML += '<div class="row">';                   
		resultHTML += '<div class="col-3 fw-bold"><?php echo $locale_text["GPSMAP_name"]; ?></div>';
		resultHTML += '<div class="col-3 border-end">' +  mapGlobals.selectedCustomer.name + '</div>'; 
		resultHTML += '<div class="col-3 fw-bold"><?php echo $locale_text["GPSMAP_phone"]; ?></div>';
		resultHTML += '<div class="col-3">' +  (mapGlobals.selectedCustomer.contactPhone !== null && mapGlobals.selectedCustomer.contactPhone.toUpperCase() != 'NULL' ? mapGlobals.selectedCustomer.contactPhone : "") + '</div>';
		resultHTML += "</div>";

		resultHTML += '<div class="row">';                   
		resultHTML += '<div class="col-3 fw-bold"><?php echo $locale_text["GPSMAP_location"]; ?></div>';
		resultHTML += '<div class="col-3 border-end">' +  (mapGlobals.selectedCustomer.location !== null && mapGlobals.selectedCustomer.location.toUpperCase() != 'NULL' ? mapGlobals.selectedCustomer.location : "") + '</div>'; 
		resultHTML += '<div class="col-3 fw-bold"><?php echo $locale_text["GPSMAP_cell_phone"]; ?></div>';
		resultHTML += '<div class="col-3">' +  (mapGlobals.selectedCustomer.contactMobile !== null && mapGlobals.selectedCustomer.contactMobile.toUpperCase() != 'NULL' ? mapGlobals.selectedCustomer.contactMobile : "") + '</div>';
		resultHTML += "</div>";

		resultHTML += '<div class="row">';                   
		resultHTML += '<div class="col-3 fw-bold"><?php echo $locale_text["GPSMAP_address"]; ?></div>';
		resultHTML += '<div class="col-3 border-end">' +  (mapGlobals.selectedCustomer.street !== null && mapGlobals.selectedCustomer.street.toUpperCase() != 'NULL' ? mapGlobals.selectedCustomer.street : "") + '</div>'; 
		resultHTML += '<div class="col-3 fw-bold"><?php echo $locale_text["GPSMAP_fax"]; ?></div>';
		resultHTML += '<div class="col-3">' +  (mapGlobals.selectedCustomer.contactFax !== null && mapGlobals.selectedCustomer.contactFax.toUpperCase() != 'NULL' ? mapGlobals.selectedCustomer.contactFax : "") + '</div>'; 
		resultHTML += "</div>";

		resultHTML += '<div class="row">';                   
		resultHTML += '<div class="col-3 fw-bold"><?php echo $locale_text["GPSMAP_zip_city"]; ?></div>';
		resultHTML += '<div class="col-3 border-end">' +  (mapGlobals.selectedCustomer.zipCode !== null && mapGlobals.selectedCustomer.zipCode.toUpperCase() != 'NULL' ? mapGlobals.selectedCustomer.zipCode : "") + " " + (mapGlobals.selectedCustomer.city !== null && mapGlobals.selectedCustomer.city.toUpperCase() != 'NULL' ? mapGlobals.selectedCustomer.city : "") + '</div>'; 
		resultHTML += '<div class="col-3 fw-bold"><?php echo $locale_text["GPSMAP_email"]; ?></div>';
		resultHTML += '<div class="col-3">' +  (mapGlobals.selectedCustomer.contactEmail !== null && mapGlobals.selectedCustomer.contactEmail.toUpperCase() != 'NULL' ? mapGlobals.selectedCustomer.contactEmail : "") + '</div>'; 
		resultHTML += "</div>";

		resultHTML += '<div class="row">';                   
		resultHTML += '<div class="col-3 fw-bold"><?php echo $locale_text["GPSMAP_country"]; ?></div>';
		resultHTML += '<div class="col-3 border-end">' +  (mapGlobals.selectedCustomer.country !== null && mapGlobals.selectedCustomer.country.toUpperCase() != 'NULL' ? mapGlobals.selectedCustomer.country : "") + '</div>'; 
		resultHTML += '<div class="col-3 fw-bold"></div>';
		resultHTML += '<div class="col-3"></div>';
		resultHTML += "</div>";

        // Initialize popover with the fetched content
        $icon.popover({
			title: "<?php echo $locale_text["GPSMAP_info"] ?>",
            trigger: "manual",
            placement: "right",
            html: true,
			customClass: "wide-popover",
            content: resultHTML
        });
		
		// Attach the event listener for 'inserted.bs.popover' before showing the popover
		$icon.on('inserted.bs.popover', function () {
			// Bind click event to each .custResultLine element within the popover
			$('.popover-body .custResultLine').on('click', function () {
				fillInMachineInfo(this.id); 
			});
		});
		
		// Show the popover
        $icon.popover("show");
		
    });
	
	
	
    // TODO handle machines from TEO
	var customerReferenceListContainer = $("#customerReferenceListContainer");
	customerReferenceListContainer.addClass("d-none");
	$("#referenceSearchWrapper").addClass("d-none");
	getServiceUnitList(refID);
	
    
    /*
	var customerReferenceListContainer = $("#customerReferenceListContainer");
	customerReferenceListContainer.addClass("hidden");
    var refFilter = $("#referenceSearchWrapper");
	refFilter.addClass("hidden"); 
	getReferenceList(refID, "ul", customerReferenceListContainer);
	*/
}


//=============================================================================
// Fill infoWindow
//=============================================================================
function fillInfoWindow(markerData){
	var html = "";
	switch(markerData.type){
		case "customer" :
			html =	"<div>" +
						"<div class='infoWindowHeader'>" +
							markerData.description +	
						"</div>" +
						"<div class='infoWindowInfoCol'>" +
							$("#custLocation").text() + "<br />" +
							$("#custAddress").text() + "<br />" +
							$("#custZipCity").text() +
						"</div>" +
					"</div>";
			break;
		case "home" :
			html =	"<div>" +
						"<div class='infoWindowHeader'>" +
							"<?php echo $locale_text["GPSMAP_legendHome"]; ?>" +
						"</div>" +
						"<div style='margin-top: 5px;'>" +
							markerData.address + 
						"</div>" + 
						"</div>" +
					"</div>";
			break;
		case "department" :
            var IDarray = markerData.id.split('_');
            var theID = "dep_"+ IDarray[1];
            var contactInfo = "";
            if (mapGlobals.JSON_departmentContact[theID]["contactPerson"]) contactInfo += mapGlobals.JSON_departmentContact[theID]["contactPerson"];
            if (mapGlobals.JSON_departmentContact[theID]["contactEmail"]) contactInfo +=  ", " + mapGlobals.JSON_departmentContact[theID]["contactEmail"];
            if (mapGlobals.JSON_departmentContact[theID]["contactPhoneNumber"]) contactInfo +=  ", " +  mapGlobals.JSON_departmentContact[theID]["contactPhoneNumber"];
            if (mapGlobals.JSON_departmentContact[theID]["contactMobilePhoneNumber"]) contactInfo +=  ", " +  mapGlobals.JSON_departmentContact[theID]["contactMobilePhoneNumber"];
            if (mapGlobals.JSON_departmentContact[theID]["contactFaxNumber"]) contactInfo +=  ", " +  mapGlobals.JSON_departmentContact[theID]["contactFaxNumber"];
			html =	"<div>" +
						"<div class='infoWindowHeader'>" +
							markerData.description +
						"</div>" +
						"<div style='margin-top: 5px;'>" +
							markerData.address +
						"</div>" +
                        "<div style='margin-top: 5px;'>" +
							contactInfo +
                        "</div>" +
					"</div>";
			break;
		case "machine" :
			html =	"<div>" +
						"<div class='infoWindowHeader'>" +
							markerData.description +
						"</div>" +
						"<div style='margin-top: 5px;'>" +
							markerData.address + 
						"</div>" + 
						"</div>" +
					"</div>";
			break;

	}
	return html;
}


//=============================================================================
// jQuery - Ready
//=============================================================================
$(document).ready(function() {
	
	$("#loginOrganizationName").html(" " + loginOrganizationName);
		
	//get initial data from REEFT 2.0
	getJobstatus();
	getActTypes();

	// rotate carets
	document.querySelectorAll('.btn-toggle').forEach(button => {
		button.addEventListener('click', function () {
			const icon = this.querySelector('.toggle-icon');
			icon.classList.toggle('rotate');
		});
	});
	
	// show sidebar at load
	toggleSidebar();
	$("#job-message").addClass("d-none");
	
	$('.sideCollapsible').on('shown.bs.collapse', function () {
		if ($('#empInfoModal').hasClass('show')) {
			$('#empInfoModal').modal('hide'); // Close the modal
		}
	})
	
	//	Customer search result hover effect
	$("#customerSearchResult, #addressSearchResult").on("mouseenter", "li.custResultLink", function(){
		$(this).addClass("custResultLinkHover");
	});
	
	//	Customer search result hover effect	
	$("#customerSearchResult, #addressSearchResult").on("mouseleave", "li.custResultLink", function(){
		$(this).removeClass("custResultLinkHover");
	});
	
	// Reset the value on page refresh
	$('#addressSearchVal').val('');
	$('#customerSearchVal').val('');
	
	//	Perform customer search
	$("#customerSearchBtn").click(function(){
		var searchString = $("#customerSearchVal").val();
		if (searchString.length < 3) {
			alert("<?php echo $locale_text["ERROR_MIN3"]; ?>");
		} else {
			customerSearch();
		}
	});
	
	// Remove customer  
    $("#hideCustomerBtn").click(function(event){
        if(mapGlobals.currentCustomerMarker != undefined){
            removeMarker(mapGlobals.currentCustomerMarker);
        }
        for(var i in mapGlobals.selectedMachines){
            removeMarker(mapGlobals.selectedMachines[i]);
            if(i in mapGlobals.selectedMachines){	//	if key exists, it might not because of async revers geo code
                        delete mapGlobals.selectedMachines[i];
                    }
        }
        mapGlobals.selectedCustomer = "";
        $("#custNumber").html("");
        $("#custName").html("");
        $("#custLocation").html("");
        $("#custAddress").html("");
        $("#custZipCity").html("");
        $("#refFilter").val("");
        $("#createJobFromCustomerBtn").addClass("mapBtnDisabled");
        if($("#createJobWindow").is(":visible")){
            $("#createJobWindow").addClass("hidden");
            resetCreateJobWindow();
        }
        $("#customerReferenceListContainer").addClass("d-none");
        $("#refFilterResult").hide();
        $("#referenceSearchWrapper").hide();
        mapGlobals.custSearching = false;
        $("#hideCustomerBtn").addClass('d-none');
		$('#createCustomerJobBtn').prop('disabled', true);
	});
	
	//create job for selected customer
	$("#createCustomerJobBtn").click(function(){
		if(mapGlobals.selectedCustomer != ""){
            jobCreate(mapGlobals.selectedCustomer);
		}
		else{
			alert("<?php echo $locale_text["ERROR_CHOOSE_CUST"]; ?>");
		}
	});
	
	//	Select an employee and shows it on map
	$("#employeeListContainer").on("click", ".listItem", function(){
		//if(!mapGlobals.depListShow){	//	If deplist is shown click wont fire on emplist.			
			var personID = $(this).attr("id").split("_");
			personID = personID[1];
			if(!$(this).hasClass("listItemOn")){
				if (typeof carData[personID] !== "undefined" && carData[personID] !== null) {
					var markerData = carData[personID]["marker"];
					addMarker(markerData);
					if(mapGlobals.callMapCenter){  //  Is not called when using show all btn to trigger click on the listitem.
						setMapCenter(markerData.latLng);
					}
					if($.inArray(personID, mapGlobals.selectedEmployees) == -1){
						mapGlobals.selectedEmployees.push(personID);
					}
					$(this).addClass("listItemOn");
				} else {
					alert("<?php echo $locale_text["GPSMAP_unknown_location"]; ?>");
				}
			}
			else{
				removeEmployeeMarker(personID);
				var persIndex = $.inArray(personID, mapGlobals.selectedEmployees);
				if(persIndex != -1){
					mapGlobals.selectedEmployees.splice(persIndex, 1);
				}
				$(this).removeClass("listItemOn");
			}
		//}
	});
	
	// Show all gps emps
    $("#showAllEmpsBtn").click(function(){
        mapGlobals.callMapCenter = false;
        $(this).addClass("d-none");
        $("#hideAllEmpsBtn").removeClass("d-none");
        $("#employeeListContainer li.listItem:not(.listItemOn):not(.d-none)").each(function(index){
            $(this).trigger("click");
        });
        mapGlobals.callMapCenter = true;        
    });
    
    //  Hide all gps emps
    $("#hideAllEmpsBtn").click(function(){
        $(this).addClass("d-none");
        $("#showAllEmpsBtn").removeClass("d-none");
        var markers = mapGlobals.markerCluster.getMarkers();
        var markersEmpArr = [];
        for (i = 0; i < markers.length; i++) {
          var markerId = markers[i].id.split("_"); 
           if(markerId[0] == "em") {
              markersEmpArr.push(markers[i]);
           }
           
        }
        mapGlobals.markerCluster.removeMarkers(markersEmpArr);
        $("#employeeListContainer li.listItemOn:not(.d-none)").each(function(){
            $(this).trigger("click");
        });
    });	
	//	Select a job and shows it on map
	$("#jobListContainer").on("click", ".jobListItem", function(){		
		const targetClass = event.target.className;
		
		var jobID = $(this).attr("id").split("_");
		jobID = jobID[1];
        
		const thisJob = mapGlobals.JSON_jobList[jobID];
		const thisJobAdress = mapGlobals.JSON_jobList[jobID]["address"];
		
        var address 			= thisJob.address;
        var description 		= thisJob.shortDescription;
        var taskStatus 			= thisJob.jobStatus;
        var taskLatitude 		= thisJob.latitude;
        var taskLongitude 		= thisJob.longitude;
        var taskPlannedperson 	= thisJob.assignedTo;
		var taskUuid			= thisJob.id;
		var customerUuid		= thisJob.customerId;
		var serviceUnitUuid		= thisJob.serviceUnitId;
        var markerID = $(this).attr("id");
		
		var thisLi = $(this);
		
        if(address != ""){
            $(this).toggleClass("listItemOn");
            
            if($(this).hasClass("listItemOn")){
                var markerData = new MarkerData("job", "", address, markerID, description, "", taskLatitude, taskLongitude,"",taskStatus, taskPlannedperson, taskUuid);
                geoCodeAddress(markerData);
            }
            else{
                removeMarker(mapGlobals.selectedJobs[markerID]);
                mapGlobals.markerCluster.removeMarker(mapGlobals.selectedJobs[markerID]);
                if(markerID in mapGlobals.selectedJobs){	//	if key exists, it might not because of async revers geo code
                    delete mapGlobals.selectedJobs[markerID];
                }
            }
        } else {
			
			parmData = 'taskUuid='+taskUuid
						;
						
			if (typeof customerUuid !== "undefined" && customerUuid !== null && customerUuid != "null") parmData += '&customerUuid='+customerUuid;
			if (typeof serviceUnitUuid !== "undefined" && serviceUnitUuid !== null && serviceUnitUuid != "null") parmData += '&serviceUnitUuid='+serviceUnitUuid;
						
			$.ajax({
				cache: false,
				url: "ajax_get_jobaddress.php",
				data: parmData,
				dataType: "json",
				success: function(jsonDataAddr){
					//console.log(jsonDataAddr);
					
					if (jsonDataAddr["error"] != "") {
						console.log(jsonDataAddr["error"]);
					} else {
						delete jsonDataAddr["error"];
						
						const jobData = jsonDataAddr[0]; 
					
						const longitude					= jobData["longitude"];
						const latitude					= jobData["latitude"];
						const location					= jobData["location"];
						const street					= jobData["street"];
						const zipCode					= jobData["zipCode"];
						const city						= jobData["city"];
						const country					= jobData["country"];
						
						var address	 	= location + " " + street + " " + zipCode + " " + city + " " + country;
						address = address.replace("null", "").trim();
						
						if(address != ""){
							thisLi.toggleClass("listItemOn");
							
							if (taskLatitude != "") taskLatitude = latitude;
							if (taskLongitude != "") taskLongitude = longitude;
							
							if(thisLi.hasClass("listItemOn")){
								var markerData = new MarkerData("job", "", address, markerID, description, "", taskLatitude, taskLongitude,"",taskStatus, taskPlannedperson, taskUuid);
								geoCodeAddress(markerData);
							}
							else{
								removeMarker(mapGlobals.selectedJobs[markerID]);
								mapGlobals.markerCluster.removeMarker(mapGlobals.selectedJobs[markerID]);
								if(markerID in mapGlobals.selectedJobs){	//	if key exists, it might not because of async revers geo code
									delete mapGlobals.selectedJobs[markerID];
								}
							}
						}
					
					}
				},
				error: function(xhr, status, error) {
					console.log(error);
				}
			});
		}
	});
	
	// Show all jobs
    $("#showAllJobsBtn").click(function(){
        mapGlobals.callMapCenter = false;
        $(this).addClass("d-none");
        $("#hideAllJobsBtn").removeClass("d-none");
        $("#jobListContainer li.listItem:not(.listItemOn):not(.d-none)").each(function(index){
            $(this).trigger("click");
        });
        mapGlobals.callMapCenter = true;        
    });
    
    //  Hide all jobs
    $("#hideAllJobsBtn").click(function(){
        $(this).addClass("d-none");
        $("#showAllJobsBtn").removeClass("d-none");
        var markers = mapGlobals.markerCluster.getMarkers();
        var markersEmpArr = [];
        for (i = 0; i < markers.length; i++) {
          var markerId = markers[i].id.split("_"); 
           if(markerId[0] == "job") {
              markersEmpArr.push(markers[i]);
           }
           
        }
        mapGlobals.markerCluster.removeMarkers(markersEmpArr);
        $("#jobListContainer li.listItemOn:not(.d-none)").each(function(){
            $(this).trigger("click");
        });
    });	
	
	// select all for printing.
	$("#printGPSTransactionsAllCheck").click(function(){
		var elementsArray = document.getElementsByClassName("historyMenuPrint");
		for(var i=0; i<elementsArray.length; i++) {
			var checked  = elementsArray[i].checked;    
			if (document.getElementById("printGPSTransactionsAllCheck").checked == true) {
				elementsArray[i].checked = true;
			} else {
				elementsArray[i].checked = false;
			}
		}
		
		recalculateSummations();
	});
	
	// Hide popover when clicking outside
    $(document).on("click", function (e) {
		const $target = $(e.target);

		// Close #customerSearchBtn popover
		if (!$target.closest("#customerSearchBtn").length && !$target.closest(".popover").length) {
			$("#customerSearchBtn").popover("hide");
			custPopoverVisible 	= false;
		}

		// Close #customerInfoIcon popovers
		if (!$target.closest("#customerInfoIcon").length && !$target.closest(".popover").length) {
			$("#customerInfoIcon").popover("hide");
		}
		
		// Close addressSearchBtn popovers
		if (!$target.closest("#addressSearchBtn").length && !$target.closest(".popover").length) {
			$("#addressSearchBtn").popover("hide");
		}
		
		// Close addressSearchBtn popovers
		if (!$target.closest(".servUnitInfoIcon").length && !$target.closest(".popover").length) {
			$(".servUnitInfoIcon").popover("hide");
		}
		// Close addressSearchBtn popovers
		if (!$target.closest(".jobSearchIcon").length && !$target.closest(".popover").length) {
			$(".jobSearchIcon").popover("hide");
			// Cancel any pending popover initialization due to hoverTimeout
			clearTimeout(hoverTimeout);
		}
	
	});

	
	// Open pop up window and print dialog.
	$("#printGPSTransactions").click(function(){
		
        var printRoutes = false;
        var printJobs = false;
        var printSchemes = false;
        var printSomething = false;
        
        var elementsArray = document.getElementsByClassName("historyMenuPrint");
		
        for(var i=0; i<elementsArray.length; i++) {
            var id = elementsArray[i].id; 
            var idArr = id.split("_");
            var checked  = elementsArray[i].checked;
            if (checked) {
                printSomething = true;
                if (idArr[0] == "printRoute") printRoutes = true;
                else if (idArr[0] == "printJob") printJobs = true;
                else if (idArr[0] == "printScheme") printSchemes = true;
            }
        }
        
        if (printSomething) {
			
			$("#modal-message").removeClass("d-none").html( '<?php echo $locale_text["GPSMAP_print_wait"] ?>' );
			
            var printWin = window.open("", "printTransactions", "scrollbars=1,height=800,width=800");
			// Clear the content of the window
			printWin.document.open();
			printWin.document.writeln(""); // Optional, just to ensure it's visibly cleared
			printWin.document.close();
            
            var style = "<style>" +
                            "body{font-family: sans-serif;} " +
                            "table{border-collapse:collapse;} " +
                            "table.dataTable { width: 100%;} " +
                            "th{border-bottom: 2px solid #CCCCCC; font-size: small; padding: 5px 5px; text-align: left;} " +
                            "th{font-weight: bold;} " +
                            "td{padding: 5px; border-bottom: 1px solid #E6E6E6; text-align: left;} " +
                            ".empHeader{ margin-top: 5px; margin-bottom: 5px; font-weight: bold; }" +
                            ".jobListIconMenu{ float: right;}" +
                            "#empJobList{ list-style: none; padding: 0px;}" +
                             ".jobInfoLine{ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;} " +
                             ".jobInfoLineHeader{ overflow: hidden; text-overflow: ellipsis;	white-space: nowrap; font-weight: bold;}" + 
                            ".historyMenuPrint{display:none}" + 
                            "#empDayJobContainer{border-bottom: 1px solid #E6E6E6;}" +
                            ".jobListItem{border-top: 1px solid #E6E6E6;}" +
                            ".jobListAssignmentItem{border-top: 1px dotted #E6E6E6;}" +
                            
                        "</style>";
                   
            printWin.document.writeln(style);
        }
        if (printRoutes) {
			
            printWin.document.writeln('<div id="empDayJobContainerHeader" class="empHeader"><?php echo $locale_text["GPSMAP_route_stoptime"]; ?></div>');
			
			printWin.document.writeln('<table class="dataTable roundAllOver" cellspacing="0">');
            printWin.document.writeln('<tbody id="summationDataSection" class="dataTable">');
            
            var routeArray = document.getElementsByClassName("printRoute");
			
			// Add the header to the table
			printWin.document.writeln("<tr>");
			var headerArr = excelData[0];
			var rowContent = "";
			for (var key in headerArr) {
				if (headerArr.hasOwnProperty(key) && key !='durationRaw') {
					var cell = headerArr[key];
					rowContent += "<th>"+cell+"</th>";
				}
			}
			printWin.document.writeln(rowContent); // Create a table cell for each column
			printWin.document.writeln("</tr>");
			
            for(var i=0; i<routeArray.length; i++) {
                var checked  = routeArray[i].checked;
                if (checked) {
					
					printWin.document.writeln("<tr>");
					
					var rowArr = excelData[i+1];
					var rowContent = "";
					for (var key in rowArr) {
						if (rowArr.hasOwnProperty(key) && key !='durationRaw') {
							var cell = rowArr[key];
							rowContent += "<td>"+cell+"</td>";
						}
					}
					printWin.document.writeln(rowContent); // Create a table cell for each column
                    printWin.document.writeln("</tr>");
                }
			
            }
			
			// Add the footer to the table
			printWin.document.writeln("<tr>");
			var footerArr = excelData[excelData.length - 1];
			var rowContent = "";
			for (var key in footerArr) {
				if (footerArr.hasOwnProperty(key) && key !='durationRaw') {
					var cell = footerArr[key];
					rowContent += "<th>"+cell+"</th>";
				}
			}
			printWin.document.writeln(rowContent); // Create a table cell for each column
			printWin.document.writeln("</tr>");
               
            printWin.document.writeln('</tbody>');
            printWin.document.writeln('</table>');
        }
        
        if (printJobs) {
            printWin.document.writeln('<div id="empDayJobContainerHead" class="empHeader"><?php echo $locale_text["GPSMAP_job"]; ?></div>');
            printWin.document.writeln('<div id="empDayJobContainer">');
            printWin.document.writeln('<ul id="empJobList">');

            
            var jobArray = document.getElementsByClassName("printJob");
            for(var i=0; i<jobArray.length; i++) {
                var checked  = jobArray[i].checked;
                if (checked) {
                    var parentLI = jobArray[i].closest("li");
                    printWin.document.writeln(parentLI.outerHTML)
                }
        
            }
            
            printWin.document.writeln('</ul>');
            printWin.document.writeln('</div>');
            
            
        }
               
        if (printSchemes) {
			// Add the header to the table
            printWin.document.writeln('<div id="empTimeshemeContainerHead" class="empHeader"><?php echo $locale_text["GPSMAP_timesheet"]; ?></div>');
            printWin.document.writeln('<div id="empTimeshemeContainer">');
            printWin.document.writeln('<table class="dataTable roundAllOver" cellspacing="0">');
            printWin.document.writeln('<tbody id="sumationDataSection" class="dataTable">');
            printWin.document.writeln('<table id="empSchemeList" class="dataTable roundAllOver"><thead class="dataTable"><tr>');
            printWin.document.writeln('<th><?php echo $locale_text["GPSMAP_job"]; ?></th>');
            printWin.document.writeln('<th><?php echo $locale_text["GPSMAP_customer"]; ?></th>');
            printWin.document.writeln('<th><?php echo $locale_text["GPSMAP_address"]; ?></th>');
            printWin.document.writeln('<th><?php echo $locale_text["GPSMAP_salary_type"]; ?></th>');
            printWin.document.writeln('<th><?php echo $locale_text["GPSMAP_duration"]; ?></th>');
            printWin.document.writeln('<th></th>');
            printWin.document.writeln('</tr></thead>');
            printWin.document.writeln('<tbody>');

			var schemeArray = document.getElementsByClassName("printScheme");
			for (var i = 0; i < schemeArray.length; i++) {
				var checked = schemeArray[i].checked;
				
				if (checked) {
					printWin.document.writeln("<tr>");
					// Find the closest row (div with class "row")
					var parentRow = schemeArray[i].closest(".row");
					
					if (parentRow) {
						// Select all divs where the class starts with "col-"
						var cols = parentRow.querySelectorAll('[class^="col-"]');
						
						// Extract text content from each column
						var colTexts = [];
						for (var j = 0; j < cols.length; j++) {
							var text = cols[j].textContent.trim();
							printWin.document.writeln("<td>"+text+"</td>");
						}
					}
					printWin.document.writeln("</tr>");
				}
			}

            printWin.document.writeln('</tbody>');
            printWin.document.writeln('</table>');
            printWin.document.writeln('</div>');
            
            
        }
        
        if (printSomething) {
			$("#modal-message").addClass("d-none").html( '' );
            printWin.print();
            printWin.document.close();  //  IE wont print unless document is closed.
        }
        
	});
	
	// Open pop up window and print dialog.
	$("#printPeriodGPSTransactions").click(function(){
		
		$("#modal-message").removeClass("d-none").html( '<?php echo $locale_text["GPSMAP_print_wait"] ?>' );
		
        var printWin = window.open("", "printTransactions", "scrollbars=1,height=800,width=800");
        
		var style = "<style>" +
						"body{font-family: sans-serif;} " +
						"table{border-collapse:collapse;} " +
						"th{border-bottom: 2px solid #CCCCCC; border-top: 2px solid #CCCCCC; font-size: small; padding: 5px 5px; text-align: left;} " +
						"th{font-weight: bold;} " +
                        "td{padding: 5px; border-bottom: 1px solid #E6E6E6; text-align: left;} " +
						".empHeader{ margin-top: 5px; margin-bottom: 5px; font-weight: bold; }" +
                    "</style>";
                     
            printWin.document.writeln(style);
			printWin.document.writeln($("#selectedEmp").html());
            printWin.document.writeln('<div id="periodContainerHeader" class="empHeader"><?php echo $locale_text["GPSMAP_route_stoptime"]; ?></div>');
		
			printWin.document.writeln('<table class="dataTable roundAllOver" cellspacing="0">');
            printWin.document.writeln('<tbody id="summationDataSection" class="dataTable">');
		
            for(var i=0; i<excelData.length; i++) {
				
				printWin.document.writeln("<tr>");
				
				var rowArr = excelData[i];
				var rowContent = "";
				for (var key in rowArr) {
					if (rowArr.hasOwnProperty(key) && key !='durationRaw') {
						var cell = rowArr[key];
						rowContent += "<td>"+cell+"</td>";
					}
				}
				printWin.document.writeln(rowContent); // Create a table cell for each column
                printWin.document.writeln("</tr>");
            }
		
			printWin.document.writeln('</tbody>');
            printWin.document.writeln('</table>');
			
			$("#modal-message").addClass("d-none").html( '' );
			
            printWin.print();
            printWin.document.close();  //  IE wont print unless document is closed.
			
			
	});
	
	//Excel buttons (day and period)
    $(".excelBtn").click(function(){
        var filename = "Reeft_GPS";
		
        var ws = XLSX.utils.json_to_sheet(excelData, {skipHeader:true});
        var wb = XLSX.utils.book_new();
        
        // calculate column width 
        const jsonKeys = Object.keys(excelData[0]);
		
        
        var objectMaxLength = []; 
        for (var i = 0; i < excelData.length; i++) {
            var value = excelData[i];
            for (var j = 0; j < jsonKeys.length; j++) {
                if (typeof value[jsonKeys[j]] == "number") {
                  objectMaxLength[j] = 10;
                } else {
                  const l = (value[jsonKeys[j]] ? value[jsonKeys[j]].length : 0);
                  objectMaxLength[j] = (objectMaxLength[j] >= l ? objectMaxLength[j] : l);
                }
            }
        }
        
        const wscols = objectMaxLength.map(w => { return { wch: w} });   //width, wch (char), wpx (pixel)
        ws["!cols"] = wscols;
        
        XLSX.utils.book_append_sheet(wb, ws, filename);
        XLSX.writeFile(wb,filename+".xlsx");
        
    });
	
	// customer search
	$(document).keydown(function(event){
		if(!mapGlobals.custSearching){
			if($("#customerSearchVal").is(":focus")){
				if(event.keyCode == 13){    // Enter
					$("#custSearhBtn").trigger("click");
				}
			}
		}
		if(event.keyCode == 27){  // Escape
		    if($("#customerSearchResult").is(":visible")){
		        mapGlobals.custSearching = false;
                $("#customerSearchResult")
                    .hide()
                    .html("");
				$("#customerSearchResultUL").html("");
		    }
		}
	});
	
	// Selected departments
	$("#depListDropDown").change(function() {
		var selectedDep = $('#depListDropDown').val();
		const employeeShowOffline = $('#employeeShowOffline').prop('checked');
		
		if (selectedDep.length > 0) {
		
			// Iterate through each <li> in the list
			$("#employeeList li").each(function() {
				// Get the class list of the current <li>
				const classList = $(this).attr("class");
				var id = $(this).attr("id");
				var idArr = id.split("_");
				var imei = idArr[1];
				var markerData = carData[imei]["marker"];

				// Find the part after "dep_"
				// [\w-] matches word characters (letters, digits, underscores) and hyphens (-).
				const depMatch = classList.match(/dep_([\w-]+)/);

				if (depMatch && selectedDep.includes(depMatch[1])) {
					if (employeeShowOffline || !$(this).hasClass('isOffline') ) {
						$(this).removeClass('d-none');
						addMarker(markerData);
						$("#emp_" + imei).addClass("listItemOn");
					}
				} else {
					$(this).addClass('d-none');
					removeEmployeeMarker(imei);
					$("#emp_" + imei).removeClass("listItemOn");
				}
			});
		
		} else {
			$("#employeeList li").each(function() {
				// Get the class list of the current <li>
				const classList = $(this).attr("class");
				var id = $(this).attr("id");
				var idArr = id.split("_");
				var imei = idArr[1];
				var markerData = carData[imei]["marker"];

				if (employeeShowOffline || !$(this).hasClass('isOffline') ) {
					$(this).removeClass('d-none');
					addMarker(markerData);
					$("#emp_" + imei).addClass("listItemOn");
				}

			});
		}
		
	})
	
	// Selected departments joblist
	$("#jobDepListDropDown").change(function() {
		var selectedDep = $('#jobDepListDropDown').val();
		
		if (selectedDep.length > 0) {
		
			// Iterate through each option in the list for employee
			$("#jobEmpListDropDown option").each(function() {
				// Get the class list of the current <li>
				const classList = $(this).attr("class");
				
				// Find the part after "dep_"
				// [\w-] matches word characters (letters, digits, underscores) and hyphens (-).
				const depMatch = classList.match(/dep_([\w-]+)/);;
				
				if ((depMatch && selectedDep.includes(depMatch[1])) || $(this).hasClass('allDep')) {
					$(this).removeClass('d-none');
					$(this).prop("disabled", false); // Ensure the option is enabled
				} else {
					$(this).addClass('d-none');
					$(this).prop("disabled", true); // Disable the option to hide it in Chosen
				}
			});
			
			// Refresh Chosen to reflect the changes for employee
			$("#jobEmpListDropDown").trigger("chosen:updated");
		
		} else {
			//employee
			$("#jobEmpListDropDown option").each(function() {
				$(this).removeClass('d-none');
				$(this).prop("disabled", false); // Ensure the option is enabled
			});
			
			$("#jobEmpListDropDown").trigger("chosen:updated");
			
		}
		
	})
	
	// Selected departments jobcreate
	$("#jobCreateDepListDropDown").change(function() {
		var selectedDep = $('#jobCreateDepListDropDown').val();
		
		$("#jobCreate-message").addClass("d-none").html( '' );
		
		if (selectedDep.length > 0) {
		
			// Iterate through each option in the list for employee
			$("#jobCreateEmpListDropDown option").each(function() {
				// Get the class list of the current <li>
				const classList = $(this).attr("class");
				
				// Find the part after "dep_"
				// [\w-] matches word characters (letters, digits, underscores) and hyphens (-).
				const depMatch = classList.match(/dep_([\w-]+)/);;
				
				if ((depMatch && selectedDep.includes(depMatch[1])) || $(this).hasClass('allDep')) {
					$(this).removeClass('d-none');
					$(this).prop("disabled", false); // Ensure the option is enabled
				} else {
					$(this).addClass('d-none');
					$(this).prop("disabled", true); // Disable the option to hide it in Chosen
				}
			});
			
			// Refresh Chosen to reflect the changes for employee
			$("#jobCreateEmpListDropDown").trigger("chosen:updated");
		
		} else {
			//employee
			$("#jobCreateEmpListDropDown option").each(function() {
				$(this).removeClass('d-none');
				$(this).prop("disabled", false); // Ensure the option is enabled
			});
			
			$("#jobCreateEmpListDropDown").trigger("chosen:updated");
			
		}
		
	})
	
	//online
	$('#employeeShowOffline').change(function() {
		const isChecked = $(this).prop('checked');
		if (isChecked) {
			$('.isOffline').removeClass('d-none');
		} else {
			$('.isOffline').addClass('d-none');
		}
		
		$('.isOffline').each(function() {
			var id = this.id;
			var idArr = id.split("_");
			var imei = idArr[1];
			var markerData = carData[imei]["marker"];
			
			if (isChecked) {
				addMarker(markerData);
				$("#emp_" + imei).addClass("listItemOn");
			} else {
				removeEmployeeMarker(imei);
				$("#emp_" + imei).removeClass("listItemOn");
			}

		});
	})
	
	//hide show routes
	$("#showRouteBtn").click(function(){
		$(".listIconShowRoute").removeClass("d-none");
		$(".listIconHideRoute").addClass("d-none");
		$(this).addClass("d-none");
        $("#hideRouteBtn").removeClass("d-none");
        $("#hideRouteIcon").removeClass("d-none");
		removePolyline(mapGlobals.routePolyline);
		showRoute();
	});
	
	$("#hideRouteBtn").click(function(){
		$(".listIconShowRoute").removeClass("d-none");
		$(".listIconHideRoute").addClass("d-none");
		$(this).addClass("d-none");
        $("#showRouteBtn").removeClass("d-none");
        $("#showRouteIcon").removeClass("d-none");
		removeAllMarkers(mapGlobals.gpsEmpLocationMarkers);
		removePolyline(mapGlobals.routePolyline);
		removeMarker(mapGlobals.clickedPolyLineMarker);
	});
	
	//hide route when modal closes
	$("#empInfoModal").on("hidden.bs.modal", function () {
		$("#hideRouteBtn").click();
	});
	
	//toogle emp modal
	$('#collapseModalToggle').on('click', function () {
            const collapseBody = $('#collapse-body');
            const icon = $(this).find('.toggle-icon');

            // Toggle the collapse state
            collapseBody.collapse('toggle');

            // Change icon based on collapse state
            collapseBody.on('shown.bs.collapse', function () {
                icon.removeClass('fa-circle-caret-down').addClass('fa-circle-caret-up');
            });
            collapseBody.on('hidden.bs.collapse', function () {
                icon.removeClass('fa-circle-caret-up').addClass('fa-circle-caret-down');
            });
        });
	
	// Set focus on tabs
	$('#home-tab').on('shown.bs.tab', function () {  
		$("#modal-message").addClass("d-none");
		$("#hideRouteBtn").click();
	})
	$('#day-tab').on('shown.bs.tab', function () {  
		$("#modal-message").addClass("d-none");
		$('#day-dateInput').focus();
	})
	$('#period-tab').on('shown.bs.tab', function () {  
		$("#modal-message").addClass("d-none");
		$("#hideRouteBtn").click();
		$('#period-fromdateInput').focus();
	})
	
	//Handle All day in jobcreate
	$("#jobCreateDayCheckbox").change(function () {
		$("#jobCreate-message").addClass("d-none").html( '' );
        if ($(this).is(":checked")) {
            var selectedDep = $('#jobCreateDepListDropDown').val();
			if (selectedDep == "") {
				$("#jobCreate-message").removeClass("d-none").html( '<?php echo $locale_text["ERROR_CHOOSE_DEP"] ?>' );
				$("#jobCreateDayCheckbox").prop("checked", false);
				$('#jobCreateDepListDropDown').focus();
			} else {
				const jobDate = $('#jobCreateDateInput').val();
				var todayNumber = new Date(jobDate).getDay();
				
				if ( todayNumber == 0 ) todayNumber = 6;
				else todayNumber = todayNumber - 1;
				
				parmData = 'depUuid='+selectedDep
						;
				$.ajax({
					cache: false,
					url: "ajax_get_availability.php",
					data: parmData,
					dataType: "json",
					success: function(jsonDataDetail){
						//console.log(jsonDataDetail);
						
						if (jsonDataDetail["error"] != "") {
							console.log(jsonDataDetail["error"]);
						} else {
							delete jsonDataDetail["error"];
							
							const availData = jsonDataDetail[todayNumber]; 
							
							$('#jobCreateFromtimeInput').val(availData['startTimeOnly']);
							$('#jobCreateTotimeInput').val(availData['endTimeOnly']);
							
							
						}
					},
					error: function(xhr, status, error) {
						console.log(error);
					}
				});
			}
        } else {
        
            $("#jobCreate-message").addClass("d-none").html( '' );
        }
    });
	
	//submit new job
	$("#jobCreateForm").submit(function (e) {
            e.preventDefault(); // Prevent default form submission
			
			$("#jobCreate-message").addClass("d-none");

            const selectedCust = $('#jobCreateModal-custId').val();
            const selectedServiceUnit = $('#jobCreateModal-serviceunitId').val();
            const selectedDep = $('#jobCreateDepListDropDown').val();
            const selectedActType = $('#jobCreateActTypeListDropDown').val();
            const selectedEmp = $('#jobCreateEmpListDropDown').val();
            const jobName = $('#jobCreateNameInput').val();
            const jobDescription = $('#jobCreateDescriptionInput').val();
			const jobDate = $('#jobCreateDateInput').val();
            const fromTime = $('#jobCreateFromtimeInput').val();
            const toTime = $('#jobCreateTotimeInput').val();

            // Validate Department and Employee
            if (!selectedCust) {
                $("#jobCreate-message").removeClass("d-none").html( '<?php echo $locale_text["ERROR_CHOOSE_CUST"] ?>' );
                return;
            }
            if (!selectedDep) {
                $("#jobCreate-message").removeClass("d-none").html( '<?php echo $locale_text["ERROR_CHOOSE_DEP"] ?>' );
				$('#jobCreateDepListDropDown').focus();
                return;
            }
            if (!selectedActType) {
                $("#jobCreate-message").removeClass("d-none").html( '<?php echo $locale_text["ERROR_CHOOSE_ACT"] ?>' );
				$('#jobCreateActTypeListDropDown').focus();
                return;
            }
            if (jobName.trim() == "" ) {
                $("#jobCreate-message").removeClass("d-none").html( '<?php echo $locale_text["ERROR_CHOOSE_JOBNAME"] ?>' );
				$('#jobName').focus();
                return;
            }
            if (!jobDate) {
                $("#jobCreate-message").removeClass("d-none").html( '<?php echo $locale_text["ERROR_DATE_WARNING"] ?>' );
				$('#jobCreateDateInput').focus();
                return;
            }
            if (!fromTime) {
                $("#jobCreate-message").removeClass("d-none").html( '<?php echo $locale_text["ERROR_FROMDATE_WARNING"] ?>' );
				$('#jobCreateFromtimeInput').focus();
                return;
            }
            if (!toTime) {
                $("#jobCreate-message").removeClass("d-none").html( '<?php echo $locale_text["ERROR_TODATE_WARNING"] ?>' );
				$('#jobCreateTotimeInput').focus();
                return;
            }
            if (fromTime > toTime) {
                $("#jobCreate-message").removeClass("d-none").html( '<?php echo $locale_text["ERROR_DATE_GREATER"] ?>' );
				$('#jobCreateFromtimeInput').focus();
                return;
            }

            // If valid submit
            parmData = 'accountId='+selectedCust
				+ '&departmentId=' + selectedDep
				+ '&activityTypeId=' + selectedActType
				+ '&selectedEmp=' + selectedEmp
				+ '&selectedServiceUnit=' + selectedServiceUnit
				+ '&shortDescription=' + jobName
				+ '&longDescription=' + jobDescription
				+ '&startDate=' + jobDate
				+ '&fromTime=' + fromTime
				+ '&toTime=' + toTime
				;
				
            $.ajax({
				cache: false,
				url: "ajax_create_job.php",
				data: parmData,
				method: 'POST',
				dataType: "json",
				success: function(jsonData){
					//console.log(jsonData);
					
					if (jsonData["error"] != "") {
						console.log(jsonData["error"]);
						$("#jobCreate-message").removeClass("d-none").html( '<?php echo $locale_text["ERROR_JOBCREATE"] ?>' + ' - ' + jsonData["error"] );
					} else {
						delete jsonData["error"];
						
						const jobId = jsonData["jobId"];
						if (!jobId) {
							$("#jobCreate-message").removeClass("d-none").html( '<?php echo $locale_text["ERROR_JOBCREATE"]?>' );
						} else {
							$('#jobCreateModal').modal('hide'); // Close the modal
						}
					}
				},
				error: function(xhr, status, error) {
					console.log(error);
				}
			});
        });
	
});


//=============================================================================
//	Constructors
//=============================================================================

// Contruct new MarkerData obj.

function MarkerData(type, latLng, address, id, description, online, latitude, longitude, course, taskStatus, taskPlannedperson, taskUuid){
	
	this.type = type;
	this.latLng = latLng;
	this.latitude = latitude;
	this.longitude = longitude;
    this.address = address;
	this.id = id;
	this.description = description;
	this.online = online;
	this.course = course;
	this.taskStatus = taskStatus;
    this.taskPlannedperson = taskPlannedperson;
    this.taskUuid = taskUuid;
}

// -->
</script>

</head>

<body>

<div class="container-fluid mt-2">
    <div class="card">
        <div class="card-header">
			<div class="row mt-2">
				<div class="col-2 h4">
					<img src="images/reeft_logo.png" alt="REEFTwebplanner" />
				</div>
				<div class="col-8 h2 text-center">
					<span class="font-weight-bold"><i class="fa fa-car">&nbsp;&nbsp;</i><?php echo $locale_text["GPSMAP_gps"] ?> <span id ="loginOrganizationName"></span></span>
				</div>
				<div class="col-2 text-end">
					<span id="toggle-btn" onclick="toggleSidebar()"><?php echo $locale_text["GPSMAP_menu_show"] ?></span><br>
					<span id="close-btn" onclick="window.close()"><i class="fa-solid fa-right-from-bracket"></i></span>
				</div>
			</div>
		</div>
		
        <div class="card-body" id="mapContainer">

            <!-- Sidebar -->
            <div class="sidebar overflow-auto" id="sidebar">
                <ul class="list-unstyled ps-0">
				<!-- Customer -->
					<li class="mb-1">
						<button class="btn btn-toggle d-flex justify-content-between align-items-center rounded collapsed" data-bs-toggle="collapse" data-bs-target="#customerCollapse" aria-expanded="false">
							<span>
								<i class="fa fa-user fa-fw me-2"></i><?php echo $locale_text["GPSMAP_customer"]; ?>
							</span>
							<i class="fa-sharp fa-solid fa-circle-caret-down toggle-icon"></i>
						</button>
						<div class="collapse sideCollapsible" id="customerCollapse">
							<div class="input-group my-3" id="customerSearchWrapper">
								<input type="text" id="customerSearchVal" class="form-control" placeholder="<?php echo $locale_text["GPSMAP_writesearch"]; ?>" aria-label="<?php echo $locale_text["GPSMAP_customer"]; ?>" aria-describedby="customerSearchBtn" onkeyup="getCustomerListTimer(false);">
								<span class="input-group-text" id="customerSearchBtn"><i class="fa-sharp fa-thin fa-magnifying-glass"></i></span>
							</div>
							<div id="customerContentWrapper">
								<div class="row mt-2">
									<div class="col-5">
										<?php echo $locale_text["GPSMAP_number"]; ?>
									</div>
									<div class="col-7 d-flex justify-content-between align-items-center" id="custNumber">
									</div>
								</div>
								<div class="row mt-2">
									<div class="col-5">
										<?php echo $locale_text["GPSMAP_name"]; ?>
									</div>
									<div class="col-7" id="custName">
									</div>
								</div>
								<div class="row mt-2">
									<div class="col-5">
										<?php echo $locale_text["GPSMAP_location"]; ?>
									</div>
									<div class="col-7" id="custLocation">
									</div>
								</div>
								<div class="row mt-2">
									<div class="col-5">
										<?php echo $locale_text["GPSMAP_address"]; ?>
									</div>
									<div class="col-7" id="custAddress">
									</div>
								</div>
								<div class="row mt-2">
									<div class="col-5">
										<?php echo $locale_text["GPSMAP_zip_city"]; ?>
									</div>
									<div class="col-7" id="custZipCity">
									</div>
								</div>
							</div>
							<div class="border-top my-3"></div>
							<div id="referenceSearchWrapper" class="inputWrapperField inputWrapperFieldSearch d-none" title="<?php echo $locale_text["GPSMAP_filter"]; ?>">
								<input type='text' class='customInput searchField' id='refFilter' onkeyup='referenceFilter()' style='width: 100%;' placeholder='<?php echo $locale_text["GPSMAP_filter"]; ?>'>
								<div class="border-top my-3"></div>
							</div>
							
							<div id="refFilterResult" style="display: none;"><?php echo $locale_text["GPSMAP_noData"]; ?></div>
							<div id="customerReferenceListContainer" class="contentSection d-none"></div>
							
							<button type="button" id="hideCustomerBtn" class="btn btn-sm btn-secondary d-none"><?php echo $locale_text["GPSMAP_clearBtn"]; ?></button>
							<button type="button" id="createCustomerJobBtn" class="btn btn-sm btn-secondary" disabled><?php echo $locale_text["GPSMAP_create_job"]; ?> <i class="fa-regular fa-calendar-circle-plus"></i></button>
							
						
					</li>
					<!-- Employees -->
					<li class="border-top my-3"></li>
					<li class="mb-1">
						<button class="btn btn-toggle d-flex justify-content-between align-items-center rounded collapsed" data-bs-toggle="collapse" data-bs-target="#employeesCollapse" aria-expanded="false">
							<span>
								<i class="fa-sharp fa-light fa-truck me-2"></i><?php echo $locale_text["GPSMAP_employees"]; ?>
							</span>
							<i class="fa-sharp fa-solid fa-circle-caret-down toggle-icon"></i>
						</button>
						<div class="collapse sideCollapsible" id="employeesCollapse">
							<div class="form-check form-switch">
								<input class="form-check-input" type="checkbox" role="switch" id="employeeShowOffline">
								<label class="form-check-label" for="employeeShowOffline"><?php echo $locale_text["GPSMAP_offline_show"]; ?></label>
							</div>

							<select id="depListDropDown" name="depListDropDown" data-placeholder="<?php echo $locale_text["GPSMAP_department"]; ?>" multiple></select>
							<div id="employeeListContainer" class="my-2">
								<ul id="employeeList" name="employeeList" class="list-group"></ul>
							</div>
							
							<button id="showAllEmpsBtn" type="button" class="btn btn-sm btn-secondary d-none"><?php echo $locale_text["GPSMAP_showAll"] ?></button>
							<button id="hideAllEmpsBtn" type="button" class="btn btn-sm btn-secondary"><?php echo $locale_text["GPSMAP_hideAll"] ?></button>
							
						</div>
					</li>
					<!-- Job -->
					<li class="border-top my-3"></li>
					<li class="mb-1">
						<button class="btn btn-toggle d-flex justify-content-between align-items-center rounded collapsed" data-bs-toggle="collapse" data-bs-target="#jobCollapse" aria-expanded="false">
							<span>
								<i class="fa-solid fa-square-list me-2"></i><?php echo $locale_text["GPSMAP_job_list"]; ?>
							</span>
							<i class="fa-sharp fa-solid fa-circle-caret-down toggle-icon"></i>
						</button>
						<div class="collapse sideCollapsible" id="jobCollapse">
							<div class="mb-1"><select id="jobDepListDropDown" name="jobDepListDropDown" data-placeholder="<?php echo $locale_text["GPSMAP_department"]; ?>" multiple></select></div>
							<div class="mb-1"><select id="jobEmpListDropDown" name="jobEmpListDropDown" data-placeholder="<?php echo $locale_text["GPSMAP_employees"]; ?>" multiple></select></div>
							<div class="mb-1"><select id="jobStatusListDropDown" name="jobStatusListDropDown" data-placeholder="<?php echo $locale_text["GPSMAP_status"]; ?>" multiple></select></div>
							<div class="mb-1"><select id="jobActTypeListDropDown" name="jobActTypeListDropDown" data-placeholder="<?php echo $locale_text["GPSMAP_act_type"]; ?>" multiple></select></div>
							
							<div class="mb-1">
								<label for="job-fromdateInput" class="col-form-label"><?php echo $locale_text["GPSMAP_period"]; ?></label>
								<div class="input-group">
									  <span class="input-group-text"><?php echo $locale_text["GPSMAP_from"] ?></span>
									<input type="date" value="<?php echo date('Y-m-d'); ?>" class="form-control" id="job-fromdateInput">
								</div>
							</div>
							
							<div class="mb-1">
								<div class="input-group">
									  <span class="input-group-text"><?php echo $locale_text["GPSMAP_to"] ?></span>
									<input type="date" value="<?php echo date('Y-m-d', strtotime("+ 1 month")); ?>" class="form-control" id="job-todateInput">
								</div>
							</div>
							
							<div class="row mb-1">
								<div class="col-6">
									<button id="getJobBtn" type="button" class="btn btn-sm btn-secondary" onclick="getJoblist()"><?php echo $locale_text["GPSMAP_load_job_list"] ?></button>
								</div>
								<div class="col-6">
									<div class="col-6 form-check form-switch">
										<input class="form-check-input" type="checkbox" role="switch" id="jobGetUnassigned">
										<label class="form-check-label" for="jobGetUnassigned"><?php echo $locale_text["GPSMAP_include_pool_job"]; ?></label>
									</div>
								</div>
							</div>
							<div class="d-none my-2 p-2 font-weight-bold border border-danger border-4 rounded" id="job-message">&nbsp;</div>
							
							<div id="jobListContainer" class="mb-2">
								<div id="jobListSpinner" class="d-none">
									<div class="spinner-border spinner-border-sm"aria-hidden="true"></div>
									<span role="status"><?php echo $locale_text["GPSMAP_loading"]; ?></span>
								</div>
								<ul id="mainJobList" name="mainJobList" class="list-group"></ul>
							</div>
							
							<button id="showAllJobsBtn" type="button" class="btn btn-sm btn-secondary d-none"><?php echo $locale_text["GPSMAP_showAll"] ?></button>
							<button id="hideAllJobsBtn" type="button" class="btn btn-sm btn-secondary d-none"><?php echo $locale_text["GPSMAP_hideAll"] ?></button>
							<button id="clearAllJobsBtn" type="button" onclick="clearJoblist()" class="btn btn-sm btn-secondary d-none"><?php echo $locale_text["GPSMAP_clearBtn"] ?></button>
							
						</div>
					<li class="border-top my-3"></li>
					<!-- Search -->
					<li class="mb-1">
						<button class="btn btn-toggle d-flex justify-content-between align-items-center rounded collapsed" data-bs-toggle="collapse" data-bs-target="#addressSearchCollapse" aria-expanded="false">
							<span>
								<i class="fa-solid fa-building-magnifying-glass me-2"></i></i><?php echo $locale_text["GPSMAP_addresssearch"]; ?>
							</span>
							<i class="fa-sharp fa-solid fa-circle-caret-down toggle-icon"></i>
						</button>
						<div class="collapse sideCollapsible" id="addressSearchCollapse">
							<div class="input-group my-3" id="addressSearchWrapper">
								<span class="input-group-text" id="addressClearBtn" onclick="addressClear()" title="<?php echo $locale_text["GPSMAP_clearBtn"]; ?>"><i class="fa-light fa-square-xmark"></i></span>
								<input type="text" id="addressSearchVal" class="form-control" placeholder="<?php echo $locale_text["GPSMAP_search"]; ?>" aria-label="<?php echo $locale_text["GPSMAP_addresssearch"]; ?>" aria-describedby="addressSearchBtn">
								<span class="input-group-text" id="addressSearchBtn" onclick="addressSearch()"><i class="fa-sharp fa-thin fa-magnifying-glass"></i></span>
							</div>
							<div id="addressSearchResult" class="resultList" style="display: none; width: 300px;"></div>
						</div>
					</li>
					<li class="border-top my-3"></li>
				</ul>
            </div>

            <!-- Map Container -->
            <div class="map-container" id="map"></div>
			
        </div>
		
    </div>
</div>

<!-- Set footer -->
<?php
	include "include/footer.php";
?>
<!-- Set footer -->

<!-- ========================================================================== -->
<!--                                M O D A L S                                 -->
<!-- ========================================================================== -->

<!-- Modal start - employee info -->
<div class="modal fade" id="empInfoModal" tabindex="-1" data-bs-backdrop="static" aria-labelledby="empInfoModalLabel" aria-hidden="true">
	<div class="modal-dialog modal-lg">
		<div class="modal-content opacity-85">
			<div class="modal-header d-flex justify-content-between align-items-center">
				<h5 class="modal-title" id="empInfoModalLabel"><?php echo $locale_text["GPSMAP_info"] ?></h5>
				<div class="d-flex align-items-center">
					<button type="button" class="btn" id="collapseModalToggle" aria-expanded="true" aria-controls="collapse-body">
						<i class="fa-sharp fa-solid fa-circle-caret-up toggle-icon"></i>
					</button>
					<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
				</div>
			</div>
			<div class="collapse show" id="collapse-body">
				<div id="empInfoModal-body" class="modal-body overflow-auto" style="max-height: 60vh;">
					<input class="d-none" type="text" id="empInfoModal-userId">
					<input class="d-none" type="text" id="empInfoModal-deviceId">
					<div class="d-none mb-2 p-2 font-weight-bold border border-danger border-4 rounded" id="modal-message">&nbsp;</div>
					
					<!-- Tabs Navigation -->
					<ul class="nav nav-tabs" id="infoTabs" role="tablist">
						<li class="nav-item" role="presentation">
							<button class="nav-link active" id="home-tab" data-bs-toggle="tab" data-bs-target="#home" type="button" role="tab" aria-controls="home" aria-selected="true"><?php echo $locale_text["GPSMAP_info"] ?></button>
						</li>
						<li class="nav-item" role="presentation">
							<button class="nav-link" id="day-tab" data-bs-toggle="tab" data-bs-target="#day" on type="button" role="tab" aria-controls="day" aria-selected="false"><?php echo $locale_text["GPSMAP_day"] ?></button>
						</li>
						<li class="nav-item" role="presentation">
							<button class="nav-link" id="period-tab" data-bs-toggle="tab" data-bs-target="#period" type="button" role="tab" aria-controls="period" aria-selected="false"><?php echo $locale_text["GPSMAP_period"] ?></button>
						</li>
					</ul>
					<!-- Tabs Info Content -->
					<div class="tab-content" id="infoTabContent">
						<div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
							<div class="row mt-3">
								<label for="empTodayJobContainer" class="col-form-label"><?php echo $locale_text["GPSMAP_scheduled_jobs"]; ?></label>
								<div id="empTodayJobContainer">
								<div class="spinner-border spinner-border-sm"aria-hidden="true"></div>
								<span role="status"><?php echo $locale_text["GPSMAP_loading"]; ?></span></div>
							</div>
						</div>
						<!-- Tabs Day Content -->
						<div class="tab-pane fade" id="day" role="tabpanel" aria-labelledby="day-tab">
							<div class="row mt-3">
								<div class="col-2">
									<label for="day-dateInput" class="col-form-label"><?php echo $locale_text["GPSMAP_select_date"]; ?></label>
								</div>
								<div class="col-3">
									<input type="date" max="<?php echo date('Y-m-d'); ?>" value="<?php echo date('Y-m-d'); ?>" class="form-control" id="day-dateInput">
								</div>
								<div class="col-2">
									<button id="getrouteBtnDay" type="button" class="btn btn-secondary" onclick="getDayData()"><?php echo $locale_text["GPSMAP_search"] ?></button>
								</div>
								<div id ="printCol" class="col-5 text-end col-disabled">
									<span id="printGPSTransactionsAll"><?php echo $locale_text["GPSMAP_print_all"]; ?>&nbsp<input type="checkbox" id="printGPSTransactionsAllCheck" name="printGPSTransactionsAllCheck" value="yes">&nbsp&nbsp</span>
									<span id="printGPSTransactions" title="<?php echo $locale_text["GPSMAP_print_driving_report"]; ?>"><i class="fa-light fa-print"></i></span>
								</div>
							</div>
							<div class="row mt-3">
								<div class="col-4 text-start">
									<?php echo $locale_text["GPSMAP_route_stoptime"]; ?>
								</div>
								<div class="col-4 text-center">
									<span id="showRouteBtn" class="routeBtn"><?php echo $locale_text["GPSMAP_showWholeRoute"]; ?> &nbsp; <span id="showRouteIcon" class='listIcon listIconShowRoute cursorPointer' title='<?php echo $locale_text["GPSMAP_showRoute"]; ?>' ><i class="fad fa-route fa-fw" style="color: red;"></i></span></span>
									<span id="hideRouteBtn" class="routeBtn d-none"><?php echo $locale_text["GPSMAP_hideWholeRoute"]; ?> &nbsp; <span id="hideRouteIcon" class='listIcon listIconHideRoute cursorPointer' title='<?php echo $locale_text["GPSMAP_hideRoute"]; ?>' ><i class="fad fa-route fa-fw"></i></span>
								</div>
								<div id ="printExcelCol" class="col-4 text-end col-disabled">
									<span class="excelBtn" title="<?php echo $locale_text["GPSMAP_excel"]; ?>"><i class="fa-light fa-file-excel"></i></span>&nbsp&nbsp
								</div>
							</div>
							<div class="row mt-3">
								<div id="day-gpsContainer" class="container"></div>
								<input id="totalDistanceSummation_hidden" type="hidden">
								<input id="totalDurationSummation_hidden" type="hidden">
							</div>
							<div class="row mt-3">
								<label for="day-JobContainer" class="col-form-label"><?php echo $locale_text["GPSMAP_job"]; ?></label>
								<div id="day-JobContainer" class="container"></div>
							</div>
							<div class="row mt-3">
								<label for="day-timesheetContainer" class="col-form-label"><?php echo $locale_text["GPSMAP_timesheet"]; ?></label>
								<div id="day-timesheetContainer" class="container"></div>
							</div>
						</div>
						<!-- Tabs Period Content -->
						<div class="tab-pane fade" id="period" role="tabpanel" aria-labelledby="period-tab">
							<div class="row mt-3">
								<div class="col-2">
									<label for="period-fromdateInput" class="col-form-label"><?php echo $locale_text["GPSMAP_select_period"]; ?></label>
								</div>
								<div class="col-3">
									<input type="date" max="<?php echo date('Y-m-d'); ?>" value="<?php echo date('Y-m-d', strtotime("-2 days")); ?>" class="form-control" id="period-fromdateInput">
								</div>
								<div class="col-1">
									<label for="period-todateInput" class="col-form-label"><?php echo $locale_text["GPSMAP_to"] ?></label>
								</div>
								<div class="col-3">
									<input type="date" max="<?php echo date('Y-m-d'); ?>" value="<?php echo date('Y-m-d', strtotime("-1 days")); ?>" class="form-control" id="period-todateInput">
								</div>
								<div class="col-2">
									<button id="getrouteBtnPeriod" type="button" class="btn btn-secondary" onclick="getRoute('*PERIOD*')"><?php echo $locale_text["GPSMAP_search"] ?></button>
								</div>
							</div>
							<div class="row mt-3">
								<div class="col-4 text-start">
									<?php echo $locale_text["GPSMAP_route_stoptime"]; ?>
								</div>
								<div class="col-4 text-center">
								</div>
								<div id ="printPeriodCol" class="col-4 text-end">
									<span class="excelBtn" title="<?php echo $locale_text["GPSMAP_excel"]; ?>"><i class="fa-light fa-file-excel"></i></span>&nbsp&nbsp
									<span id="printPeriodGPSTransactions" title="<?php echo $locale_text["GPSMAP_print_driving_report"]; ?>"><i class="fa-light fa-print"></i></span>
								</div>
							</div>
							
							<div class="row mt-3">
								<div id="period-gpsContainer" class="container"></div>
							</div>
							
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>
</div>

<!-- Modal end -->


<!-- Modal start - jobcreate -->
<div class="modal fade" id="jobCreateModal" tabindex="-1" data-bs-backdrop="static" aria-labelledby="jobCreateModalLabel" aria-hidden="true">
	<div class="modal-dialog modal-lg">
		<div class="modal-content opacity-85">
			<div class="modal-header d-flex justify-content-between align-items-center">
				<h5 class="modal-title" id="jobCreateModalLabel"><?php echo $locale_text["GPSMAP_create_job"] ?></h5>
				<div class="d-flex align-items-center">
					<button type="button" class="btn" id="collapseModalToggle" aria-expanded="true" aria-controls="collapse-body">
						<i class="fa-sharp fa-solid fa-circle-caret-up toggle-icon"></i>
					</button>
					<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
				</div>
			</div>
			<div class="collapse show" id="collapse-body">
				<div id="jobCreateModal-body" class="modal-body overflow-auto" >
					<form id="jobCreateForm">
						<input class="d-none" type="text" id="jobCreateModal-custId">
						<input class="d-none" type="text" id="jobCreateModal-serviceunitId">
						
							<div class="row mb-3 align-items-center">
								<div class="col-md-6">
									<label for="jobCreateDepListDropDown" class="form-label"><?php echo $locale_text["GPSMAP_department"] ?></label>
									<select id="jobCreateDepListDropDown" name="jobCreateDepListDropDown" class="form-select"> </select>
								</div>
								<div class="col-md-6">
									<label for="jobCreateActTypeListDropDown" class="form-label"><?php echo $locale_text["GPSMAP_act_type"] ?></label>
									<select id="jobCreateActTypeListDropDown" name="jobCreateActTypeListDropDown" class="form-select"> </select>
								</div>
							</div>

							<div class="row mb-3 align-items-center">
								<div class="col-md-12">
									<label for="jobCreateNameInput" class="form-label"><?php echo $locale_text["GPSMAP_jobname"] ?></label>
									<input type="text" id="jobCreateNameInput" name="jobCreateNameInput" class="form-control">
								</div>
							</div>

							<div class="row mb-3 align-items-center">
								<div class="col-md-12">
									<label for="jobCreateDescriptionInput" class="form-label"><?php echo $locale_text["GPSMAP_description"] ?></label>
									<textarea id="jobCreateDescriptionInput" name="jobCreateDescriptionInput" class="form-control" rows="3"></textarea>
								</div>
							</div>

							<div class="row mb-3 align-items-center">
								<div class="col-md-3">
									<label for="jobCreateEmpListDropDown" class="form-label"><?php echo $locale_text["GPSMAP_employee"] ?></label>
									<select id="jobCreateEmpListDropDown" name="jobCreateEmpListDropDown" class="form-select"> </select>
								</div>
								<div class="col-md-3">
									<label for="jobCreateDateInput" class="form-label"><?php echo $locale_text["GPSMAP_date"] ?></label>
									<input type="date" id="jobCreateDateInput" name="jobCreateDateInput" class="form-control" min="<?php echo date('Y-m-d'); ?>" value="<?php echo date('Y-m-d'); ?>">
								</div>
								<div class="col-md-2">
									<label for="jobCreateFromtimeInput" class="form-label"><?php echo $locale_text["GPSMAP_starttime"] ?></label>
									<input type="time" id="jobCreateFromtimeInput" name="jobCreateFromtimeInput" class="form-control">
								</div>
								<div class="col-md-2">
									<label for="jobCreateTotimeInput" class="form-label"><?php echo $locale_text["GPSMAP_endtime"] ?></label>
									<input type="time" id="jobCreateTotimeInput" name="jobCreateTotimeInput" class="form-control">
								</div>
								<div class="col-md-2">
									<label for="jobCreateDayCheckbox" class="form-label"><?php echo $locale_text["GPSMAP_allday"] ?></label>
									<div class="form-check">
										<input class="form-check-input" type="checkbox" id="jobCreateDayCheckbox" name="jobCreateDayCheckbox">
									</div>
								</div>
							</div>
							
							<div class="d-none my-2 p-2 font-weight-bold border border-danger border-4 rounded" id="jobCreate-message">&nbsp;</div>
							
							<div class="row">
								<div class="col">
									<button type="submit" class="btn btn-secondary"><?php echo $locale_text["GPSMAP_save"] ?></button>
								</div>
							</div>
							 
							
						</form>		
				</div>
			</div>
		</div>
	</div>
</div>

<!-- Modal end -->


<!-- Define initMap as a global function, placed here to ensure everything is read in DOM -->
<script>

window.initMap = function() {
    var location = { lat: dftMapCenterLat, lng: dftMapCenterLng };
	
	var mapOptions = { 
           zoom: dftZoomlevel,
           center: location
       };
	
    mapGlobals.map = new google.maps.Map(document.getElementById('map'), mapOptions);

	overlay = new google.maps.OverlayView();
	overlay.draw = function() {};
	overlay.setMap(mapGlobals.map); 
	
	mapGlobals.infoWin = new google.maps.InfoWindow();	//	Popup window for markers
       
    var getGoogleClusterInlineSvg = function (color) {
		var encoded = window.btoa('<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-100 -100 200 200"><defs><g id="a" transform="rotate(45)"><path d="M0 47A47 47 0 0 0 47 0L62 0A62 62 0 0 1 0 62Z" fill-opacity="0.7" stroke="#C3C3C3" stroke-width="1"/><path d="M0 67A67 67 0 0 0 67 0L81 0A81 81 0 0 1 0 81Z" fill-opacity="0.5" stroke="#C3C3C3" stroke-width="1"/><path d="M0 86A86 86 0 0 0 86 0L100 0A100 100 0 0 1 0 100Z" fill-opacity="0.3" stroke="#C3C3C3" stroke-width="1"/></g></defs><g fill="' + color + '"><circle r="42" stroke="#C3C3C3" stroke-width="2"/><use xlink:href="#a"/><g transform="rotate(120)"><use xlink:href="#a"/></g><g transform="rotate(240)"><use xlink:href="#a"/></g></g></svg>');
	
		return ('data:image/svg+xml;base64,' + encoded);
	};
     
	var cluster_styles = [
        {
            width: 70,
            height: 70,
            url: getGoogleClusterInlineSvg('<?php echo $DFT_COLOR_JOB_NOT_ASSIGNED; ?>'),
            textSize: 12
        },
        {
            width: 70,
            height: 70,
            url: getGoogleClusterInlineSvg('<?php echo $DFT_COLOR_JOB_ACTIVE; ?>'),
            textSize: 12
        },
        {
            width: 70,
            height: 70,
            url: getGoogleClusterInlineSvg('<?php echo $DFT_COLOR_JOB_START; ?>'),
            textSize: 12
        },
        {
            width: 70,
            height: 70,
            url: getGoogleClusterInlineSvg('<?php echo $DFT_COLOR_JOB_ONHOLD; ?>'),
            textSize: 12
        },
        {
            width: 70,
            height: 70,
            url: getGoogleClusterInlineSvg('<?php echo $DFT_COLOR_JOB_REVIEW; ?>'),
            textSize: 12
        },
        {
            width: 70,
            height: 70,
            url: getGoogleClusterInlineSvg('<?php echo $DFT_COLOR_JOB_CLOSED; ?>'),
            textSize: 12
        },
        {
            width: 70,
            height: 70,
            url: getGoogleClusterInlineSvg('<?php echo $DFT_COLOR_JOB_INVOICED; ?>'),
            textSize: 12
        },
        {
            width: 70,
            height: 70,
            url: getGoogleClusterInlineSvg('<?php echo $DFT_COLOR_JOB_CANCEL; ?>'),
            textSize: 12
        },
        {
            width: 70,
            height: 70,
            url: getGoogleClusterInlineSvg('#C3C3C3'),
            textSize: 12
        },
        
    ];


    var clusterOptions = {
        zoomOnClick: false,
        averageCenter: true,
        styles: cluster_styles,
        gridSize: 5,
		debug: true // Enable debugging
    }
	
	
    mapGlobals.markerCluster = new MarkerClusterer(mapGlobals.map, [], clusterOptions);
	
    /** 
	* It's important to remember that this function runs for EACH cluster individually.
	* @param  {Array} markers Set of markers for this cluster.
	* @param {Number} numStyles Number of styles we have to play with (set in clusterOptions).
	*/
	mapGlobals.markerCluster.setCalculator(function(markers, numStyles){
		
		var index = 0;
        var count = markers.length;
        var dv = count;
		
        while (dv !== 0) {
            dv = parseInt(dv / 10, 10);
            index++;
        }

        index = Math.min(index, numStyles);
		
        //max jobstatus is 7, so 8 indicates only workers        
        var minStatus = 8;   

        markers.forEach(function(marker) {
            if(marker.taskStatus != ""){
                tmpStatus = parseInt(marker.taskStatus);
                minStatus = Math.min(status,minStatus);
            } 
        });

        return {
            text: count,
            index: minStatus
    };
	});
    
    google.maps.event.addListener(mapGlobals.markerCluster, 'clusterclick', function(cluster){
        mapGlobals.infoBubble = new InfoBubble({
          maxWidth: 300
        });
        var markers = cluster.getMarkers();
        var showEmp = false;
        var showJob = false;
        var infoTextEmp = "<ul>";
        var infoTextJob = "<ul>";
        for (i = 0; i < markers.length; i++) {
          var markerId = markers[i].id.split("_"); 
          if(markerId[0] == "em") {
            showEmp = true;
			var init = "";
			try {
				var init = mapGlobals.JSON_employeeList[markerId[1]].initials;
			}
			catch(err) {
				return;
			}
			var empName = mapGlobals.JSON_employeeList[markerId[1]].name;
			var phone = mapGlobals.JSON_employeeList[markerId[1]].phone;
			
			infoTextEmp += "(" + init + ")" + " " + empName + " " + phone + "<br>";
          } else {
            showJob = true;
            var description = "";
            try {
				var description = mapGlobals.selectedJobs[markers[i].id].title;
			}
			catch(err) {
				return;
			}
            
            var icon = mapGlobals.selectedJobs[markers[i].id].icon;
            var iconPath = icon.split(".");
            var color = iconPath[0].split("_");
            
            var taskPlannedperson =  mapGlobals.selectedJobs[markers[i].id].taskPlannedperson;
            var tmpEditLink = "";
            
            if(mapGlobals.userLevel != 1) {
              //  Planner / admins can change all jobs
              tmpEditLink = "onclick=\"return showJobdetails(" +markerId[1]+ ")\"";
            } else {
              //  Regular user may only change own job.
              if(mapGlobals.loggedInUser == taskPlannedperson || mapGlobals.loggedInUser == 0) {
                tmpEditLink = "onclick=\"return showJobdetails(" +markerId[1]+ ")\"";
              } else {
                tmpEditLink = "onclick=\"javascript:alert('<?php echo $locale_text["ERROR_EDIT_NOT_ALLOWED"];?>')\"";
              }
            }
            
            infoTextJob += "<li style='background-color: #"+color[2]+";'><span "+tmpEditLink+" class='markerInfoIcon cursorPointer' title= '<?php echo $locale_text["GPSMAP_job_info"];	?>' style='padding-top: 16px;'></span><span style='color: #000000; font-weight: bold;'> " + " " + description + "</span></li>";  
          }
        }
        infoTextEmp += "</ul>";
        infoTextJob += "</ul>";
       
       var markerTmp = new google.maps.Marker({
          position: cluster.getCenter(),
          draggable: false
        });
       if (showJob) {
           mapGlobals.infoBubble.addTab('<?php echo $locale_text["GPSMAP_job_list"];	?> ', infoTextJob);
       }
       if (showEmp) {
           mapGlobals.infoBubble.addTab('<?php echo $locale_text["GPSMAP_employees"];	?> ', infoTextEmp);
       }       
       mapGlobals.infoBubble.open(mapGlobals.map, markerTmp);
        
    });
		
	getCarlocations("**FIRST**");
	//call getCarlocations runs every 60 sec
	setTimeout(() => {
		getCarlocations("**LATEST**");
		setInterval(() => getCarlocations("**LATEST**"), 60000); 
	}, 60000);
}
</script>

</body>
</html>